Logo ROOT  
Reference Guide
TApplicationServer.cxx
Go to the documentation of this file.
1// @(#)root/net:$Id$
2// Author: G. Ganis 10/5/2007
3
4/*************************************************************************
5 * Copyright (C) 1995-2007, Rene Brun and Fons Rademakers. *
6 * All rights reserved. *
7 * *
8 * For the licensing terms see $ROOTSYS/LICENSE. *
9 * For the list of contributors see $ROOTSYS/README/CREDITS. *
10 *************************************************************************/
11
12//////////////////////////////////////////////////////////////////////////
13// //
14// TApplicationServer //
15// //
16// TApplicationServer is the remote application run by the roots main //
17// program. The input is taken from the socket connection to the client.//
18// //
19//////////////////////////////////////////////////////////////////////////
20
21#include "RConfigure.h"
22#include <ROOT/RConfig.hxx>
23#include "snprintf.h"
24#include <iostream>
25
26#ifdef WIN32
27 #include <io.h>
28 typedef long off_t;
29#endif
30#include <cstdlib>
31#include <cerrno>
32#include <ctime>
33#include <fcntl.h>
34#include <sys/types.h>
35#include <sys/stat.h>
36
37#if (defined(__FreeBSD__) && (__FreeBSD__ < 4)) || \
38 (defined(__APPLE__) && (!defined(MAC_OS_X_VERSION_10_3) || \
39 (MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_3)))
40#include <sys/file.h>
41#define lockf(fd, op, sz) flock((fd), (op))
42#ifndef F_LOCK
43#define F_LOCK (LOCK_EX | LOCK_NB)
44#endif
45#ifndef F_ULOCK
46#define F_ULOCK LOCK_UN
47#endif
48#endif
49
50#include "RRemoteProtocol.h"
51
52#include "TApplicationServer.h"
53#include "TBenchmark.h"
54#include "TEnv.h"
55#include "TError.h"
56#include "TException.h"
57#include "TInterpreter.h"
58#include "TMD5.h"
59#include "TMessage.h"
60#include "TROOT.h"
61#include "TSocket.h"
62#include "TSystem.h"
63#include "TRemoteObject.h"
64#include "TUrl.h"
65#include "compiledata.h"
66#include "TClass.h"
67
68
69//----- Interrupt signal handler -----------------------------------------------
70////////////////////////////////////////////////////////////////////////////////
71
74public:
77 Bool_t Notify();
78};
79
80////////////////////////////////////////////////////////////////////////////////
81/// Handle this interrupt
82
84{
86 if (TROOT::Initialized()) {
88 }
89 return kTRUE;
90}
91
92//----- SigPipe signal handler -------------------------------------------------
93////////////////////////////////////////////////////////////////////////////////
94
97public:
99 { fServ = s; }
100 Bool_t Notify();
101};
102
103////////////////////////////////////////////////////////////////////////////////
104/// Handle this signal
105
107{
109 return kTRUE;
110}
111
112//----- Input handler for messages from client -----------------------
113////////////////////////////////////////////////////////////////////////////////
114
117public:
119 { fServ = s; }
120 Bool_t Notify();
121 Bool_t ReadNotify() { return Notify(); }
122};
123
124////////////////////////////////////////////////////////////////////////////////
125/// Handle this input
126
128{
130 return kTRUE;
131}
132
133TString TASLogHandler::fgPfx = ""; // Default prefix to be prepended to messages
134////////////////////////////////////////////////////////////////////////////////
135/// Execute 'cmd' in a pipe and handle output messages from the related file
136
137TASLogHandler::TASLogHandler(const char *cmd, TSocket *s, const char *pfx)
138 : TFileHandler(-1, 1), fSocket(s), fPfx(pfx)
139{
141 fFile = 0;
142 if (s && cmd) {
143 fFile = gSystem->OpenPipe(cmd, "r");
144 if (fFile) {
145 SetFd(fileno(fFile));
146 // Notify what already in the file
147 Notify();
148 // Used in the destructor
150 } else {
151 fSocket = 0;
152 Error("TASLogHandler", "executing command in pipe");
153 }
154 } else {
155 Error("TASLogHandler",
156 "undefined command (%p) or socket (%p)", (int *)cmd, s);
157 }
158}
159////////////////////////////////////////////////////////////////////////////////
160/// Handle available message from the open file 'f'
161
162TASLogHandler::TASLogHandler(FILE *f, TSocket *s, const char *pfx)
163 : TFileHandler(-1, 1), fSocket(s), fPfx(pfx)
164{
166 fFile = 0;
167 if (s && f) {
168 fFile = f;
169 SetFd(fileno(fFile));
170 // Notify what already in the file
171 Notify();
172 } else {
173 Error("TASLogHandler", "undefined file (%p) or socket (%p)", f, s);
174 }
175}
176////////////////////////////////////////////////////////////////////////////////
177/// Handle available message in the open file
178
180{
181 if (TestBit(kFileIsPipe) && fFile)
183 fFile = 0;
184 fSocket = 0;
186}
187////////////////////////////////////////////////////////////////////////////////
188/// Handle available message in the open file
189
191{
192 if (IsValid()) {
194 // Read buffer
195 char line[4096];
196 char *plf = 0;
197 while (fgets(line, sizeof(line), fFile)) {
198 if ((plf = strchr(line, '\n')))
199 *plf = 0;
200 // Send the message one level up
201 m.Reset(kMESS_ANY);
202 m << (Int_t)kRRT_Message;
203 if (fPfx.Length() > 0) {
204 // Prepend prefix specific to this instance
205 m << TString(Form("%s: %s", fPfx.Data(), line));
206 } else if (fgPfx.Length() > 0) {
207 // Prepend default prefix
208 m << TString(Form("%s: %s", fgPfx.Data(), line));
209 } else {
210 // Nothing to prepend
211 m << TString(line);
212 }
213 fSocket->Send(m);
214 }
215 }
216 return kTRUE;
217}
218////////////////////////////////////////////////////////////////////////////////
219/// Static method to set the default prefix
220
222{
223 fgPfx = pfx;
224}
225
226////////////////////////////////////////////////////////////////////////////////
227/// Init a guard for executing a command in a pipe
228
230 const char *pfx, Bool_t on)
231{
232 fExecHandler = 0;
233 if (cmd && on) {
234 fExecHandler = new TASLogHandler(cmd, s, pfx);
235 if (fExecHandler->IsValid()) {
237 } else {
238 Error("TASLogHandlerGuard","invalid handler");
239 }
240 } else {
241 if (on)
242 Error("TASLogHandlerGuard","undefined command");
243 }
244}
245
246////////////////////////////////////////////////////////////////////////////////
247/// Init a guard for executing a command in a pipe
248
250 const char *pfx, Bool_t on)
251{
252 fExecHandler = 0;
253 if (f && on) {
254 fExecHandler = new TASLogHandler(f, s, pfx);
255 if (fExecHandler->IsValid()) {
257 } else {
258 Error("TASLogHandlerGuard","invalid handler");
259 }
260 } else {
261 if (on)
262 Error("TASLogHandlerGuard","undefined file");
263 }
264}
265
266////////////////////////////////////////////////////////////////////////////////
267/// Close a guard for executing a command in a pipe
268
270{
274 }
275}
276
278
279////////////////////////////////////////////////////////////////////////////////
280/// Main constructor. Create an application environment. The TApplicationServer
281/// environment provides an eventloop via inheritance of TApplication.
282
284 FILE *flog, const char *logfile)
285 : TApplication("server", argc, argv, 0, -1)
286{
287 // Parse options
288 GetOptions(argc, argv);
289
290 // Abort on higher than kSysError's and set error handler
293
295 fSocket = 0;
296 fWorkingDir = 0;
297
298 fLogFilePath = logfile;
299 fLogFile = flog;
300 fLogFileDes = -1;
301 if (!fLogFile || (fLogFileDes = fileno(fLogFile)) < 0)
302 // For some reason we failed setting a redirection; we cannot continue
303 Terminate(0);
305 fSentCanvases = 0;
306
307 // Default prefix for notifications
309
310 // Now we contact back the client: if we fail we set ourselves
311 // as invalid
313
314 if (!(fSocket = new TSocket(GetHost(), GetPort()))) {
315 Terminate(0);
316 return;
317 }
318 Int_t sock = fSocket->GetDescriptor();
319
320 if (Setup() != 0) {
321 Error("TApplicationServer", "failed to setup - quitting");
322 SendLogFile(-98);
323 Terminate(0);
324 }
325
326 // Everybody expects std::iostream to be available, so load it...
327 ProcessLine("#include <iostream>", kTRUE);
328 ProcessLine("#include <string>",kTRUE); // for std::string std::iostream.
329
330 // Load user functions
331 const char *logon;
332 logon = gEnv->GetValue("Rint.Load", (char *)0);
333 if (logon) {
334 char *mac = gSystem->Which(TROOT::GetMacroPath(), logon, kReadPermission);
335 if (mac)
336 ProcessLine(Form(".L %s", logon), kTRUE);
337 delete [] mac;
338 }
339
340 // Execute logon macro
341 ExecLogon();
342
343 // Init benchmarking
344 gBenchmark = new TBenchmark();
345
346 // Save current interpreter context
347 gInterpreter->SaveContext();
348 gInterpreter->SaveGlobalsContext();
349
350 // Install interrupt and message input handlers
352 gSystem->AddFileHandler(new TASInputHandler(this, sock));
353
354 // We are done
355 fIsValid = kTRUE;
356
357 // Startup notification
359 SendLogFile();
360}
361
362////////////////////////////////////////////////////////////////////////////////
363/// Print the Remote Server logo on standard output.
364/// Return 0 on success, -1 on failure
365
367{
368 char str[512];
369 snprintf(str, 512, "**** Remote session @ %s started ****", gSystem->HostName());
370 if (fSocket->Send(str) != 1+static_cast<Int_t>(strlen(str))) {
371 Error("Setup", "failed to send startup message");
372 return -1;
373 }
374
375 // Send our protocol level to the client
376 if (fSocket->Send(kRRemote_Protocol, kROOTD_PROTOCOL) != 2*sizeof(Int_t)) {
377 Error("Setup", "failed to send local protocol");
378 return -1;
379 }
380
381 // Send the host name and full path to log file
382 TMessage msg(kMESS_ANY);
383 msg << TString(gSystem->HostName()) << fLogFilePath;
384 fSocket->Send(msg);
385
386 // Set working directory
388 if (strlen(fUrl.GetFile()) > 0) {
391 }
392
393 // Go to working dir
397 SysError("Setup", "can not change to directory %s",
398 fWorkDir.Data());
399 }
400 } else {
405 SysError("Setup", "can not change to directory %s",
406 fWorkDir.Data());
407 }
408 }
409 }
410
411#if 0 // G.Ganis May 11, 2007
412 // This needs to be fixed: we disable for the time being
413 // Socket options: incoming OOB should generate a SIGURG
414 if (fSocket->SetOption(kProcessGroup, (-1)*gSystem->GetPid()) != 0)
415 SysWarning("Setup", "failed to enable SIGURG generation on incoming OOB");
416#endif
417
418 // Send messages off immediately to reduce latency
419 if (fSocket->SetOption(kNoDelay, 1) != 0) {}
420 //SysWarning("Setup", "failed to set no-delay option on input socket");
421
422 // Check every two hours if client is still alive
423 if (fSocket->SetOption(kKeepAlive, 1) != 0) {}
424 //SysWarning("Setup", "failed to set keepalive option on input socket");
425
426 // Install SigPipe handler to handle kKeepAlive failure
428
429 // Done
430 return 0;
431}
432
433////////////////////////////////////////////////////////////////////////////////
434/// Cleanup. Not really necessary since after this dtor there is no
435/// live anyway.
436
438{
443}
444
445////////////////////////////////////////////////////////////////////////////////
446/// Get and handle command line options. Fixed format:
447/// "protocol url"
448
449void TApplicationServer::GetOptions(Int_t *argc, char **argv)
450{
451 if (*argc < 4) {
452 Fatal("GetOptions", "must be started with 4 arguments");
453 gSystem->Exit(1);
454 }
455
456 // Protocol run by the client
457 fProtocol = TString(argv[1]).Atoi();
458
459 // Client URL
460 fUrl.SetUrl(argv[2]);
461
462 // Debug level
463 gDebug = 0;
464 TString argdbg(argv[3]);
465 if (argdbg.BeginsWith("-d=")) {
466 argdbg.ReplaceAll("-d=","");
467 gDebug = argdbg.Atoi();
468 }
469}
470
471////////////////////////////////////////////////////////////////////////////////
472/// Main server eventloop.
473
475{
476 // Setup the server
477 if (fIsValid) {
478 // Run the main event loop
479 TApplication::Run(retrn);
480 } else {
481 Error("Run", "invalid instance: cannot Run()");
482 gSystem->Exit(1);
483 }
484}
485
486////////////////////////////////////////////////////////////////////////////////
487/// Handle input coming from the client or from the master server.
488
490{
491 TMessage *mess;
492 char str[2048];
493 Int_t what;
494
495 if (fSocket->Recv(mess) <= 0) {
496 // Pending: do something more intelligent here
497 // but at least get a message in the log file
498 Error("HandleSocketInput", "retrieving message from input socket");
499 Terminate(0);
500 return;
501 }
502
503 what = mess->What();
504 if (gDebug > 0)
505 Info("HandleSocketInput", "got message of type %d", what);
506
507 switch (what) {
508
509 case kMESS_CINT:
511 mess->ReadString(str, sizeof(str));
512 if (gDebug > 1)
513 Info("HandleSocketInput:kMESS_CINT", "processing: %s...", str);
514 ProcessLine(str);
515 }
516 SendCanvases();
517 SendLogFile();
518 break;
519
520 case kMESS_STRING:
521 mess->ReadString(str, sizeof(str));
522 break;
523
524 case kMESS_OBJECT:
525 mess->ReadObject(mess->GetClass());
526 break;
527
528 case kMESS_ANY:
529 {
530 Int_t type;
531 (*mess) >> type;
532 switch (type) {
533 case kRRT_Reset:
534 mess->ReadString(str, sizeof(str));
535 Reset(str);
536 break;
537
538 case kRRT_CheckFile:
539 // Handle file checking request
540 HandleCheckFile(mess);
541 break;
542
543 case kRRT_File:
544 // A file follows
545 mess->ReadString(str, sizeof(str));
546 { char name[2048], i1[20], i2[40];
547 sscanf(str, "%2047s %19s %39s", name, i1, i2);
548 Int_t bin = atoi(i1);
549 Long_t size = atol(i2);
550 ReceiveFile(name, bin ? kTRUE : kFALSE, size);
551 }
552 break;
553
554 case kRRT_Terminate:
555 // Terminate the session (will not return from here)
556 Int_t status;
557 (*mess) >> status;
558 Terminate(status);
559 break;
560
561 default:
562 break;
563 }
564 }
565 SendLogFile();
566 break;
567 default:
568 Warning("HandleSocketInput","message type unknown (%d)", what);
569 SendLogFile();
570 break;
571 }
572
573 delete mess;
574}
575
576////////////////////////////////////////////////////////////////////////////////
577/// Handle Out-Of-Band data sent by the master or client.
578
580{
581 char oob_byte;
582 Int_t n, nch, wasted = 0;
583
584 const Int_t kBufSize = 1024;
585 char waste[kBufSize];
586
587 // Real-time notification of messages
589
590 Info("HandleUrgentData", "handling oob...");
591
592 // Receive the OOB byte
593 while ((n = fSocket->RecvRaw(&oob_byte, 1, kOob)) < 0) {
594 if (n == -2) { // EWOULDBLOCK
595 //
596 // The OOB data has not yet arrived: flush the input stream
597 //
598 // In some systems (Solaris) regular recv() does not return upon
599 // receipt of the oob byte, which makes the below call to recv()
600 // block indefinitely if there are no other data in the queue.
601 // FIONREAD ioctl can be used to check if there are actually any
602 // data to be flushed. If not, wait for a while for the oob byte
603 // to arrive and try to read it again.
604 //
606 if (nch == 0) {
607 gSystem->Sleep(1000);
608 continue;
609 }
610
611 if (nch > kBufSize) nch = kBufSize;
612 n = fSocket->RecvRaw(waste, nch);
613 if (n <= 0) {
614 Error("HandleUrgentData", "error receiving waste");
615 break;
616 }
617 wasted = 1;
618 } else {
619 Error("HandleUrgentData", "error receiving OOB (n = %d)",n);
620 return;
621 }
622 }
623
624 Info("HandleUrgentData", "got OOB byte: %d\n", oob_byte);
625
626 switch (oob_byte) {
627
628 case kRRI_Hard:
629 Info("HandleUrgentData", "*** Hard Interrupt");
630
631 // Flush input socket
632 while (1) {
633 Int_t atmark;
634
635 fSocket->GetOption(kAtMark, atmark);
636
637 if (atmark) {
638 // Send the OOB byte back so that the client knows where
639 // to stop flushing its input stream of obsolete messages
640 n = fSocket->SendRaw(&oob_byte, 1, kOob);
641 if (n <= 0)
642 Error("HandleUrgentData", "error sending OOB");
643 break;
644 }
645
646 // find out number of bytes to read before atmark
648 if (nch == 0) {
649 gSystem->Sleep(1000);
650 continue;
651 }
652
653 if (nch > kBufSize) nch = kBufSize;
654 n = fSocket->RecvRaw(waste, nch);
655 if (n <= 0) {
656 Error("HandleUrgentData", "error receiving waste (2)");
657 break;
658 }
659 }
660
661 SendLogFile();
662
663 break;
664
665 case kRRI_Soft:
666 Info("HandleUrgentData", "Soft Interrupt");
667
668 if (wasted) {
669 Error("HandleUrgentData", "soft interrupt flushed stream");
670 break;
671 }
672
673 Interrupt();
674
675 SendLogFile();
676
677 break;
678
679 case kRRI_Shutdown:
680 Info("HandleUrgentData", "Shutdown Interrupt");
681
682 Terminate(0);
683
684 break;
685
686 default:
687 Error("HandleUrgentData", "unexpected OOB byte");
688 break;
689 }
690}
691
692////////////////////////////////////////////////////////////////////////////////
693/// Called when the client is not alive anymore (i.e. when kKeepAlive
694/// has failed).
695
697{
698 // Real-time notification of messages
700
701 Info("HandleSigPipe", "client died");
702 Terminate(0); // will not return from here....
703}
704
705////////////////////////////////////////////////////////////////////////////////
706/// Reset environment to be ready for execution of next command.
707
708void TApplicationServer::Reset(const char *dir)
709{
710 // First go to new directory.
711 gDirectory->cd(dir);
712
713 // Clear interpreter environment.
714 gROOT->Reset();
715
716 // Make sure current directory is empty (don't delete anything when
717 // we happen to be in the ROOT memory only directory!?)
718 if (gDirectory != gROOT) {
719 gDirectory->Delete();
720 }
721}
722
723////////////////////////////////////////////////////////////////////////////////
724/// Receive a file, either sent by a client or a master server.
725/// If bin is true it is a binary file, other wise it is an ASCII
726/// file and we need to check for Windows \r tokens. Returns -1 in
727/// case of error, 0 otherwise.
728
730{
731 if (size <= 0) return 0;
732
733 // open file, overwrite already existing file
734 Int_t fd = open(file, O_CREAT | O_TRUNC | O_WRONLY, 0600);
735 if (fd < 0) {
736 SysError("ReceiveFile", "error opening file %s", file);
737 return -1;
738 }
739
740 const Int_t kMAXBUF = 16384; //32768 //16384 //65536;
741 char buf[kMAXBUF], cpy[kMAXBUF];
742
743 Int_t left, r;
744 Long64_t filesize = 0;
745
746 while (filesize < size) {
747 left = Int_t(size - filesize);
748 if (left > kMAXBUF)
749 left = kMAXBUF;
750 r = fSocket->RecvRaw(&buf, left);
751 if (r > 0) {
752 char *p = buf;
753
754 filesize += r;
755 while (r) {
756 Int_t w;
757
758 if (!bin) {
759 Int_t k = 0, i = 0, j = 0;
760 char *q;
761 while (i < r) {
762 if (p[i] == '\r') {
763 i++;
764 k++;
765 }
766 cpy[j++] = buf[i++];
767 }
768 q = cpy;
769 r -= k;
770 w = write(fd, q, r);
771 } else {
772 w = write(fd, p, r);
773 }
774
775 if (w < 0) {
776 SysError("ReceiveFile", "error writing to file %s", file);
777 close(fd);
778 return -1;
779 }
780 r -= w;
781 p += w;
782 }
783 } else if (r < 0) {
784 Error("ReceiveFile", "error during receiving file %s", file);
785 close(fd);
786 return -1;
787 }
788 }
789
790 close(fd);
791
792 chmod(file, 0644);
793
794 return 0;
795}
796
797////////////////////////////////////////////////////////////////////////////////
798/// Send log file to master.
799/// If start > -1 send only bytes in the range from start to end,
800/// if end <= start send everything from start.
801
803{
804 // Determine the number of bytes left to be read from the log file.
805 fflush(stdout);
806
807 off_t ltot=0, lnow=0;
808 Int_t left = -1;
809 Bool_t adhoc = kFALSE;
810
811 if (fLogFileDes > -1) {
812 ltot = lseek(fileno(stdout), (off_t) 0, SEEK_END);
813 lnow = lseek(fLogFileDes, (off_t) 0, SEEK_CUR);
814 if (lnow == -1) {
815 SysError("SendLogFile", "lseek failed");
816 lnow = 0;
817 }
818
819 if (start > -1) {
820 lseek(fLogFileDes, (off_t) start, SEEK_SET);
821 if (end <= start || end > ltot)
822 end = ltot;
823 left = (Int_t)(end - start);
824 if (end < ltot)
825 left++;
826 adhoc = kTRUE;
827 } else {
828 left = (Int_t)(ltot - lnow);
829 }
830 }
831
833
834 if (left > 0) {
835
836 m << (Int_t)kRRT_LogFile << left;
837 fSocket->Send(m);
838
839 const Int_t kMAXBUF = 32768; //16384 //65536;
840 char buf[kMAXBUF];
841 Int_t wanted = (left > kMAXBUF) ? kMAXBUF : left;
842 Int_t len;
843 do {
844 while ((len = read(fLogFileDes, buf, wanted)) < 0 &&
845 TSystem::GetErrno() == EINTR)
847
848 if (len < 0) {
849 SysError("SendLogFile", "error reading log file");
850 break;
851 }
852
853 if (end == ltot && len == wanted)
854 buf[len-1] = '\n';
855
856 if (fSocket->SendRaw(buf, len) < 0) {
857 SysError("SendLogFile", "error sending log file");
858 break;
859 }
860
861 // Update counters
862 left -= len;
863 wanted = (left > kMAXBUF) ? kMAXBUF : left;
864
865 } while (len > 0 && left > 0);
866 }
867
868 // Restore initial position if partial send
869 if (adhoc)
870 lseek(fLogFileDes, lnow, SEEK_SET);
871
872 m.Reset();
873 m << (Int_t)kRRT_LogDone << status;
874
875 fSocket->Send(m);
876}
877
878////////////////////////////////////////////////////////////////////////////////
879/// Send any created canvas to client
880
882{
883 Int_t nc = 0;
884
885 // Send back new canvases
887 TIter next(gROOT->GetListOfCanvases());
888 TObject *o = 0;
889 while ((o = next())) {
890 if (!fSentCanvases)
891 fSentCanvases = new TList;
892 Bool_t sentalready = kFALSE;
893 // We cannot use FindObject here because there may be invalid
894 // objects in the send list (i.e. deleted canvases)
896 while (lnk) {
897 TObject *sc = lnk->GetObject();
898 lnk = lnk->Next();
899 if ((sc->TestBit(kNotDeleted)) && sc == o)
900 sentalready = kTRUE;
901 }
902 if (!sentalready) {
903 if (gDebug > 0)
904 Info("SendCanvases","new canvas found: %p", o);
905 mess.Reset(kMESS_OBJECT);
906 mess.WriteObject(o);
907 fSocket->Send(mess);
908 nc++;
909 fSentCanvases->Add(o);
910 }
911 }
912 return nc;
913}
914
915////////////////////////////////////////////////////////////////////////////////
916/// Browse directory and send back its content to client.
917
919{
920 Int_t nc = 0;
921
923 if (!fWorkingDir || !dirname || !*dirname) {
924 if (!fWorkingDir)
925 fWorkingDir = new TRemoteObject(fWorkDir, fWorkDir, "TSystemDirectory");
926 TList *list = fWorkingDir->Browse();
927 mess.Reset(kMESS_OBJECT);
929 fSocket->Send(mess);
930 nc++;
931 list->Delete();
932 delete list;
933 }
934 else if (fWorkingDir) {
935 TRemoteObject dir(dirname, dirname, "TSystemDirectory");
936 TList *list = dir.Browse();
937 mess.Reset(kMESS_OBJECT);
938 mess.WriteObject(list);
939 fSocket->Send(mess);
940 nc++;
941 list->Delete();
942 delete list;
943 }
944 return nc;
945}
946
947////////////////////////////////////////////////////////////////////////////////
948/// Browse root file and send back its content;
949/// if fname is null, send the full list of files.
950
952{
953 Int_t nc = 0;
954
955 TList *list = new TList;
957 if (!fname || !*fname) {
958 // fname is null, so send the list of files.
959 TIter next(gROOT->GetListOfFiles());
960 TNamed *fh = 0;
961 TRemoteObject *robj;
962 while ((fh = (TNamed *)next())) {
963 robj = new TRemoteObject(fh->GetName(), fh->GetTitle(), "TFile");
964 list->Add(robj);
965 }
966 if (list->GetEntries() > 0) {
967 mess.Reset(kMESS_OBJECT);
968 mess.WriteObject(list);
969 fSocket->Send(mess);
970 nc++;
971 }
972 }
973 else {
974 // get Root file content and send the list of objects
975 TDirectory *fh = (TDirectory *)gROOT->GetListOfFiles()->FindObject(fname);
976 if (fh) {
977 fh->cd();
978 TRemoteObject dir(fh->GetName(), fh->GetTitle(), "TFile");
979 TList *keylist = (TList *)gROOT->ProcessLine(Form("((TFile *)0x%zx)->GetListOfKeys();", (size_t)fh));
980 TIter nextk(keylist);
981 TNamed *key = 0;
982 TRemoteObject *robj;
983 while ((key = (TNamed *)nextk())) {
984 robj = new TRemoteObject(key->GetName(), key->GetTitle(), "TKey");
985 const char *classname = (const char *)gROOT->ProcessLine(Form("((TKey *)0x%zx)->GetClassName();", (size_t)key));
986 robj->SetKeyClassName(classname);
987 Bool_t isFolder = (Bool_t)gROOT->ProcessLine(Form("((TKey *)0x%zx)->IsFolder();", (size_t)key));
988 robj->SetFolder(isFolder);
989 robj->SetRemoteAddress((Longptr_t) key);
990 list->Add(robj);
991 }
992 if (list->GetEntries() > 0) {
993 mess.Reset(kMESS_OBJECT);
994 mess.WriteObject(list);
995 fSocket->Send(mess);
996 nc++;
997 }
998 }
999 }
1000
1001 list->Delete();
1002 delete list;
1003
1004 return nc;
1005}
1006
1007////////////////////////////////////////////////////////////////////////////////
1008/// Read key object and send it back to client.
1009
1011{
1012 Int_t nc = 0;
1013
1014 TMessage mess(kMESS_OBJECT);
1015 TNamed *obj = (TNamed *)gROOT->ProcessLine(Form("gFile->GetKey(\"%s\")->ReadObj();", keyname));
1016 if (obj) {
1017 mess.Reset(kMESS_OBJECT);
1018 mess.WriteObject(obj);
1019 fSocket->Send(mess);
1020 nc++;
1021 }
1022 return nc;
1023}
1024
1025////////////////////////////////////////////////////////////////////////////////
1026/// Terminate the proof server.
1027
1029{
1030 // Close and remove the log file; remove the cleanup script
1031 if (fLogFile) {
1032 fclose(fLogFile);
1033 // Delete the log file unless we are in debug mode
1034 if (gDebug <= 0)
1036 TString cleanup = fLogFilePath;
1037 cleanup.ReplaceAll(".log", ".cleanup");
1038 gSystem->Unlink(cleanup);
1039 }
1040
1041 // Remove input handler to avoid spurious signals in socket
1042 // selection for closing activities executed upon exit()
1044 TObject *fh = 0;
1045 while ((fh = next())) {
1046 TASInputHandler *ih = dynamic_cast<TASInputHandler *>(fh);
1047 if (ih)
1049 }
1050
1051 // Stop processing events
1052 gSystem->Exit(status);
1053}
1054
1055////////////////////////////////////////////////////////////////////////////////
1056/// Handle file checking request.
1057
1059{
1060 TString filenam;
1061 TMD5 md5;
1063
1064 // Parse message
1065 (*mess) >> filenam >> md5;
1066
1067 // check file in working directory
1068 TMD5 *md5local = TMD5::FileChecksum(filenam);
1069 if (md5local && md5 == (*md5local)) {
1070 // We have an updated copy of the file
1071 m << (Int_t) kRRT_CheckFile << (Bool_t) kTRUE;
1072 fSocket->Send(m);
1073 if (gDebug > 0)
1074 Info("HandleCheckFile", "up-to-date version of %s available", filenam.Data());
1075 } else {
1077 fSocket->Send(m);
1078 if (gDebug > 0)
1079 Info("HandleCheckFile", "file %s needs to be uploaded", filenam.Data());
1080 }
1081 delete md5local;
1082}
1083
1084////////////////////////////////////////////////////////////////////////////////
1085/// The error handler function. It prints the message on stderr and
1086/// if abort is set it aborts the application.
1087
1088void TApplicationServer::ErrorHandler(Int_t level, Bool_t abort, const char *location,
1089 const char *msg)
1090{
1091 if (gErrorIgnoreLevel == kUnset) {
1093 if (gEnv) {
1094 TString slevel = gEnv->GetValue("Root.ErrorIgnoreLevel", "Print");
1095 if (!slevel.CompareTo("Print", TString::kIgnoreCase))
1097 else if (!slevel.CompareTo("Info", TString::kIgnoreCase))
1099 else if (!slevel.CompareTo("Warning", TString::kIgnoreCase))
1101 else if (!slevel.CompareTo("Error", TString::kIgnoreCase))
1103 else if (!slevel.CompareTo("Break", TString::kIgnoreCase))
1105 else if (!slevel.CompareTo("SysError", TString::kIgnoreCase))
1107 else if (!slevel.CompareTo("Fatal", TString::kIgnoreCase))
1109 }
1110 }
1111
1112 if (level < gErrorIgnoreLevel)
1113 return;
1114
1115 static TString syslogService;
1116
1117 if (syslogService.IsNull()) {
1118 syslogService = "server";
1119 gSystem->Openlog(syslogService, kLogPid | kLogCons, kLogLocal5);
1120 }
1121
1122 const char *type = 0;
1123 ELogLevel loglevel = kLogInfo;
1124
1125 if (level >= kPrint) {
1126 loglevel = kLogInfo;
1127 type = "Print";
1128 }
1129 if (level >= kInfo) {
1130 loglevel = kLogInfo;
1131 type = "Info";
1132 }
1133 if (level >= kWarning) {
1134 loglevel = kLogWarning;
1135 type = "Warning";
1136 }
1137 if (level >= kError) {
1138 loglevel = kLogErr;
1139 type = "Error";
1140 }
1141 if (level >= kBreak) {
1142 loglevel = kLogErr;
1143 type = "*** Break ***";
1144 }
1145 if (level >= kSysError) {
1146 loglevel = kLogErr;
1147 type = "SysError";
1148 }
1149 if (level >= kFatal) {
1150 loglevel = kLogErr;
1151 type = "Fatal";
1152 }
1153
1154 TString node = "server";
1155 TString buf;
1156
1157 if (!location || !location[0] ||
1158 (level >= kPrint && level < kInfo) ||
1159 (level >= kBreak && level < kSysError)) {
1160 fprintf(stderr, "%s on %s: %s\n", type, node.Data(), msg);
1161 buf.Form("%s:%s:%s", node.Data(), type, msg);
1162 } else {
1163 fprintf(stderr, "%s in <%s> on %s: %s\n", type, location, node.Data(), msg);
1164 buf.Form("%s:%s:<%s>:%s", node.Data(), type, location, msg);
1165 }
1166 fflush(stderr);
1167
1168 gSystem->Syslog(loglevel, buf);
1169
1170 if (abort) {
1171 fprintf(stderr, "aborting\n");
1172 fflush(stderr);
1174 gSystem->Abort();
1175 }
1176}
1177
1178////////////////////////////////////////////////////////////////////////////////
1179/// Parse a command line received from the client, making sure that the files
1180/// needed for the execution, if any, are available. The line is either a C++
1181/// statement or an interpreter command starting with a ".".
1182/// Return the return value of the command casted to a long.
1183
1185{
1186 if (!line || !*line) return 0;
1187
1188 // If load or execute request we must make sure that we have the files.
1189 // If not we ask the client to send them, blocking until we have everything.
1190 if (!strncmp(line, ".L", 2) || !strncmp(line, ".U", 2) ||
1191 !strncmp(line, ".X", 2) || !strncmp(line, ".x", 2)) {
1192 TString aclicMode;
1193 TString arguments;
1194 TString io;
1195 TString fname = gSystem->SplitAclicMode(line+3, aclicMode, arguments, io);
1196
1197 char *imp = gSystem->Which(TROOT::GetMacroPath(), fname, kReadPermission);
1198 if (!imp) {
1199
1200 // Make sure that we can write in the directory where we are
1202 Error("ProcessLine","no write permission in %s", gSystem->WorkingDirectory());
1203 return 0;
1204 }
1205
1206 if (gDebug > 0)
1207 Info("ProcessLine", "macro %s not found in path %s: asking the client",
1208 fname.Data(), TROOT::GetMacroPath());
1210 m << (Int_t) kRRT_SendFile << TString(gSystem->BaseName(fname));
1211 fSocket->Send(m);
1212
1213 // Wait for the reply(ies)
1214 Int_t type;
1215 Bool_t filefollows = kTRUE;
1216
1217 while (filefollows) {
1218
1219 // Get a message
1220 TMessage *rm = 0;
1221 if (fSocket->Recv(rm) <= 0) {
1222 Error("ProcessLine","ask-file: received empty message from client");
1223 return 0;
1224 }
1225 if (rm->What() != kMESS_ANY) {
1226 Error("ProcessLine","ask-file: wrong message received (what: %d)", rm->What());
1227 return 0;
1228 }
1229 (*rm) >> type;
1230 if (type != kRRT_SendFile) {
1231 Error("ProcessLine","ask-file: wrong sub-type received (type: %d)", type);
1232 return 0;
1233 }
1234 (*rm) >> filefollows;
1235 if (filefollows) {
1236 // Read the file specifications
1237 if (fSocket->Recv(rm) <= 0) {
1238 Error("ProcessLine","file: received empty message from client");
1239 return 0;
1240 }
1241 if (rm->What() != kMESS_ANY) {
1242 Error("ProcessLine","file: wrong message received (what: %d)", rm->What());
1243 return 0;
1244 }
1245 (*rm) >> type;
1246 if (type != kRRT_File) {
1247 Error("ProcessLine","file: wrong sub-type received (type: %d)", type);
1248 return 0;
1249 }
1250 // A file follows
1251 char str[2048];
1252 rm->ReadString(str, sizeof(str));
1253 char name[2048], i1[20], i2[40];
1254 sscanf(str, "%2047s %19s %39s", name, i1, i2);
1255 Int_t bin = atoi(i1);
1256 Long_t size = atol(i2);
1257 ReceiveFile(name, bin ? kTRUE : kFALSE, size);
1258 }
1259 }
1260 }
1261 delete [] imp;
1262 }
1263
1264 // Process the line now
1266}
1267
1268////////////////////////////////////////////////////////////////////////////////
1269/// Execute logon macro's. There are three levels of logon macros that
1270/// will be executed: the system logon etc/system.rootlogon.C, the global
1271/// user logon ~/.rootlogon.C and the local ./.rootlogon.C. For backward
1272/// compatibility also the logon macro as specified by the Rint.Logon
1273/// environment setting, by default ./rootlogon.C, will be executed.
1274/// No logon macros will be executed when the system is started with
1275/// the -n option.
1276
1278{
1279 if (NoLogOpt()) return;
1280
1281 TString name = ".rootlogon.C";
1282 TString sname = "system";
1283 sname += name;
1284 char *s = gSystem->ConcatFileName(TROOT::GetEtcDir(), sname);
1286 ProcessFile(s);
1287 }
1288 delete [] s;
1291 ProcessFile(s);
1292 }
1293 delete [] s;
1294 // avoid executing ~/.rootlogon.C twice
1295 if (strcmp(gSystem->HomeDirectory(), gSystem->WorkingDirectory())) {
1298 }
1299
1300 // execute also the logon macro specified by "Rint.Logon"
1301 const char *logon = gEnv->GetValue("Rint.Logon", (char*)0);
1302 if (logon) {
1303 char *mac = gSystem->Which(TROOT::GetMacroPath(), logon, kReadPermission);
1304 if (mac)
1305 ProcessFile(logon);
1306 delete [] mac;
1307 }
1308}
@ kMESS_STRING
Definition: MessageTypes.h:34
@ kMESS_ANY
Definition: MessageTypes.h:31
@ kMESS_OBJECT
Definition: MessageTypes.h:35
@ kROOTD_PROTOCOL
Definition: MessageTypes.h:114
@ kMESS_CINT
Definition: MessageTypes.h:36
ROOT::R::TRInterface & r
Definition: Object.C:4
#define SafeDelete(p)
Definition: RConfig.hxx:534
const Int_t kRRemote_Protocol
@ kRRT_Terminate
@ kRRT_LogFile
@ kRRT_CheckFile
@ kRRT_File
@ kRRT_LogDone
@ kRRT_Message
@ kRRT_SendFile
@ kRRT_Reset
@ kRRI_Shutdown
@ kRRI_Soft
@ kRRI_Hard
#define f(i)
Definition: RSha256.hxx:104
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
int Int_t
Definition: RtypesCore.h:45
long Longptr_t
Definition: RtypesCore.h:82
const Bool_t kFALSE
Definition: RtypesCore.h:101
long Long_t
Definition: RtypesCore.h:54
bool Bool_t
Definition: RtypesCore.h:63
long long Long64_t
Definition: RtypesCore.h:80
const Bool_t kTRUE
Definition: RtypesCore.h:100
#define ClassImp(name)
Definition: Rtypes.h:364
R__EXTERN TBenchmark * gBenchmark
Definition: TBenchmark.h:59
#define gDirectory
Definition: TDirectory.h:348
R__EXTERN TEnv * gEnv
Definition: TEnv.h:170
const Int_t kPrint
Definition: TError.h:43
const Int_t kError
Definition: TError.h:46
const Int_t kSysError
Definition: TError.h:48
const Int_t kUnset
Definition: TError.h:42
const Int_t kFatal
Definition: TError.h:49
void Error(const char *location, const char *msgfmt,...)
Use this function in case an error occurred.
Definition: TError.cxx:187
const Int_t kBreak
Definition: TError.h:47
R__EXTERN Int_t gErrorAbortLevel
Definition: TError.h:128
const Int_t kWarning
Definition: TError.h:45
R__EXTERN Int_t gErrorIgnoreLevel
Definition: TError.h:127
ErrorHandlerFunc_t SetErrorHandler(ErrorHandlerFunc_t newhandler)
Set an errorhandler function. Returns the old handler.
Definition: TError.cxx:92
const Int_t kInfo
Definition: TError.h:44
R__EXTERN void Throw(int code)
If an exception context has been set (using the TRY and RETRY macros) jump back to where it was set.
Definition: TException.cxx:27
char name[80]
Definition: TGX11.cxx:110
int type
Definition: TGX11.cxx:121
float * q
Definition: THbookFile.cxx:89
#define gInterpreter
Definition: TInterpreter.h:562
Int_t gDebug
Definition: TROOT.cxx:592
#define gROOT
Definition: TROOT.h:404
char * Form(const char *fmt,...)
@ kSigPipe
@ kSigUrgent
@ kKeepAlive
Definition: TSystem.h:219
@ kBytesToRead
Definition: TSystem.h:225
@ kNoDelay
Definition: TSystem.h:221
@ kProcessGroup
Definition: TSystem.h:223
@ kAtMark
Definition: TSystem.h:224
@ kOob
Definition: TSystem.h:230
@ kReadPermission
Definition: TSystem.h:47
@ kWritePermission
Definition: TSystem.h:46
@ kLogLocal5
Definition: TSystem.h:72
ELogLevel
Definition: TSystem.h:55
@ kLogWarning
Definition: TSystem.h:60
@ kLogInfo
Definition: TSystem.h:62
@ kLogErr
Definition: TSystem.h:59
R__EXTERN TSystem * gSystem
Definition: TSystem.h:559
@ kLogPid
Definition: TSystem.h:51
@ kLogCons
Definition: TSystem.h:52
#define snprintf
Definition: civetweb.c:1540
TASInputHandler(TApplicationServer *s, Int_t fd)
TApplicationServer * fServ
Bool_t Notify()
Handle this input.
Bool_t ReadNotify()
Notify when something can be read from the descriptor associated with this handler.
TApplicationServer * fServ
Bool_t Notify()
Handle this interrupt.
TASInterruptHandler(TApplicationServer *s)
TASLogHandlerGuard(const char *cmd, TSocket *s, const char *pfx="", Bool_t on=kTRUE)
Init a guard for executing a command in a pipe.
virtual ~TASLogHandlerGuard()
Close a guard for executing a command in a pipe.
TASLogHandler * fExecHandler
virtual ~TASLogHandler()
Handle available message in the open file.
static TString fgPfx
TASLogHandler(const char *cmd, TSocket *s, const char *pfx="")
Execute 'cmd' in a pipe and handle output messages from the related file.
Bool_t Notify()
Handle available message in the open file.
static void SetDefaultPrefix(const char *pfx)
Static method to set the default prefix.
TApplicationServer * fServ
Bool_t Notify()
Handle this signal.
TASSigPipeHandler(TApplicationServer *s)
void ExecLogon()
Execute logon macro's.
Int_t SendCanvases()
Send any created canvas to client.
void Terminate(Int_t status)
Terminate the proof server.
TApplicationServer(Int_t *argc, char **argv, FILE *flog, const char *logfile)
Main constructor.
void HandleUrgentData()
Handle Out-Of-Band data sent by the master or client.
void HandleSocketInput()
Handle input coming from the client or from the master server.
Int_t ReceiveFile(const char *file, Bool_t bin, Long64_t size)
Receive a file, either sent by a client or a master server.
const char * GetHost() const
void GetOptions(Int_t *argc, char **argv)
Get and handle command line options.
void Reset(const char *dir)
Reset environment to be ready for execution of next command.
void Run(Bool_t retrn=kFALSE)
Main server eventloop.
void HandleSigPipe()
Called when the client is not alive anymore (i.e.
TRemoteObject * fWorkingDir
static void ErrorHandler(Int_t level, Bool_t abort, const char *location, const char *msg)
The error handler function.
Int_t BrowseKey(const char *keyname)
Read key object and send it back to client.
Int_t Setup()
Print the Remote Server logo on standard output.
Int_t BrowseDirectory(const char *dirname)
Browse directory and send back its content to client.
void HandleCheckFile(TMessage *mess)
Handle file checking request.
virtual ~TApplicationServer()
Cleanup.
Longptr_t ProcessLine(const char *line, Bool_t=kFALSE, Int_t *err=0)
Parse a command line received from the client, making sure that the files needed for the execution,...
Int_t BrowseFile(const char *fname)
Browse root file and send back its content; if fname is null, send the full list of files.
void SendLogFile(Int_t status=0, Int_t start=-1, Int_t end=-1)
Send log file to master.
This class creates the ROOT Application Environment that interfaces to the windowing system eventloop...
Definition: TApplication.h:39
virtual Longptr_t ProcessLine(const char *line, Bool_t sync=kFALSE, Int_t *error=0)
virtual Longptr_t ProcessFile(const char *file, Int_t *error=0, Bool_t keep=kFALSE)
Bool_t NoLogOpt() const
Definition: TApplication.h:138
virtual void Run(Bool_t retrn=kFALSE)
This class is a ROOT utility to help benchmarking applications.
Definition: TBenchmark.h:29
TObject * ReadObject(const TClass *cl) override
Read object from I/O buffer.
char * ReadString(char *s, Int_t max) override
Read string from I/O buffer.
void WriteObject(const TObject *obj, Bool_t cacheReuse=kTRUE) override
Write object to I/O buffer.
Definition: TBufferIO.cxx:530
virtual Int_t GetEntries() const
Definition: TCollection.h:179
virtual void SetOwner(Bool_t enable=kTRUE)
Set whether this collection is the owner (enable==true) of its content.
Describe directory structure in memory.
Definition: TDirectory.h:45
virtual Bool_t cd(const char *path=nullptr)
Change current directory to "this" directory.
Definition: TDirectory.cxx:504
virtual Int_t GetValue(const char *name, Int_t dflt) const
Returns the integer value for a resource.
Definition: TEnv.cxx:491
void SetFd(int fd)
A doubly linked list.
Definition: TList.h:44
virtual void Add(TObject *obj)
Definition: TList.h:87
virtual TObjLink * FirstLink() const
Definition: TList.h:108
virtual void Delete(Option_t *option="")
Remove all objects from the list AND delete all heap based objects.
Definition: TList.cxx:470
This code implements the MD5 message-digest algorithm.
Definition: TMD5.h:44
static TMD5 * FileChecksum(const char *file)
Returns checksum of specified file.
Definition: TMD5.cxx:474
UInt_t What() const
Definition: TMessage.h:75
void Reset() override
Reset the message buffer so we can use (i.e. fill) it again.
Definition: TMessage.cxx:179
TClass * GetClass() const
Definition: TMessage.h:71
The TNamed class is the base class for all named ROOT classes.
Definition: TNamed.h:29
virtual const char * GetTitle() const
Returns title of object.
Definition: TNamed.h:48
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:47
Mother of all ROOT objects.
Definition: TObject.h:37
R__ALWAYS_INLINE Bool_t TestBit(UInt_t f) const
Definition: TObject.h:187
@ kNotDeleted
object has not been deleted
Definition: TObject.h:78
virtual void SysError(const char *method, const char *msgfmt,...) const
Issue system error message.
Definition: TObject.cxx:907
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition: TObject.cxx:879
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
Definition: TObject.cxx:696
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition: TObject.cxx:893
virtual void Fatal(const char *method, const char *msgfmt,...) const
Issue fatal error message.
Definition: TObject.cxx:921
void ResetBit(UInt_t f)
Definition: TObject.h:186
virtual void Info(const char *method, const char *msgfmt,...) const
Issue info message.
Definition: TObject.cxx:867
static const char * GetMacroPath()
Get macro search path. Static utility function.
Definition: TROOT.cxx:2715
static Bool_t Initialized()
Return kTRUE if the TROOT object has been initialized.
Definition: TROOT.cxx:2818
static const TString & GetEtcDir()
Get the sysconfig directory in the installation. Static utility function.
Definition: TROOT.cxx:2953
The TRemoteObject class provides protocol for browsing ROOT objects from a remote ROOT session.
Definition: TRemoteObject.h:34
void SetKeyClassName(const char *name)
Definition: TRemoteObject.h:59
void SetRemoteAddress(Longptr_t addr)
Definition: TRemoteObject.h:60
virtual void Browse(TBrowser *b)
Browse remote object.
void SetFolder(Bool_t isFolder)
Definition: TRemoteObject.h:57
ESignals GetSignal() const
Option_t * GetOption() const
Definition: TSocket.h:98
virtual Int_t SetOption(ESockOptions opt, Int_t val)
Set socket options.
Definition: TSocket.cxx:1013
virtual Int_t Recv(TMessage *&mess)
Receive a TMessage object.
Definition: TSocket.cxx:818
virtual Int_t RecvRaw(void *buffer, Int_t length, ESendRecvOptions opt=kDefault)
Receive a raw buffer of specified length bytes.
Definition: TSocket.cxx:898
virtual Int_t SendRaw(const void *buffer, Int_t length, ESendRecvOptions opt=kDefault)
Send a raw buffer of specified length.
Definition: TSocket.cxx:620
virtual Int_t GetDescriptor() const
Definition: TSocket.h:112
virtual Int_t Send(const TMessage &mess)
Send a TMessage object.
Definition: TSocket.cxx:522
Basic string class.
Definition: TString.h:136
Ssiz_t Length() const
Definition: TString.h:410
int CompareTo(const char *cs, ECaseCompare cmp=kExact) const
Compare a string to char *cs2.
Definition: TString.cxx:442
Int_t Atoi() const
Return integer value of string.
Definition: TString.cxx:1946
const char * Data() const
Definition: TString.h:369
TString & ReplaceAll(const TString &s1, const TString &s2)
Definition: TString.h:692
@ kIgnoreCase
Definition: TString.h:268
Bool_t BeginsWith(const char *s, ECaseCompare cmp=kExact) const
Definition: TString.h:615
Bool_t IsNull() const
Definition: TString.h:407
void Form(const char *fmt,...)
Formats a string using a printf style format descriptor.
Definition: TString.cxx:2314
virtual void AddFileHandler(TFileHandler *fh)
Add a file handler to the list of system file handlers.
Definition: TSystem.cxx:557
virtual void Syslog(ELogLevel level, const char *mess)
Send mess to syslog daemon.
Definition: TSystem.cxx:1684
static void ResetErrno()
Static function resetting system error number.
Definition: TSystem.cxx:279
virtual Bool_t ExpandPathName(TString &path)
Expand a pathname getting rid of special shell characters like ~.
Definition: TSystem.cxx:1274
virtual void Openlog(const char *name, Int_t options, ELogFacility facility)
Open connection to system log daemon.
Definition: TSystem.cxx:1675
static Int_t GetErrno()
Static function returning system error number.
Definition: TSystem.cxx:263
virtual int GetPid()
Get process id.
Definition: TSystem.cxx:710
virtual TString SplitAclicMode(const char *filename, TString &mode, TString &args, TString &io) const
This method split a filename of the form:
Definition: TSystem.cxx:4241
virtual char * ConcatFileName(const char *dir, const char *name)
Concatenate a directory and a file name. User must delete returned string.
Definition: TSystem.cxx:1071
virtual int mkdir(const char *name, Bool_t recursive=kFALSE)
Make a file system directory.
Definition: TSystem.cxx:907
virtual TFileHandler * RemoveFileHandler(TFileHandler *fh)
Remove a file handler from the list of file handlers.
Definition: TSystem.cxx:567
virtual TSeqCollection * GetListOfFileHandlers() const
Definition: TSystem.h:381
virtual FILE * OpenPipe(const char *command, const char *mode)
Open a pipe.
Definition: TSystem.cxx:665
virtual Bool_t AccessPathName(const char *path, EAccessMode mode=kFileExists)
Returns FALSE if one can access a file using the specified access mode.
Definition: TSystem.cxx:1296
virtual Bool_t ChangeDirectory(const char *path)
Change directory.
Definition: TSystem.cxx:863
virtual int ClosePipe(FILE *pipe)
Close the pipe.
Definition: TSystem.cxx:674
virtual const char * BaseName(const char *pathname)
Base name of a file name. Base name of /user/root is root.
Definition: TSystem.cxx:935
virtual void AddSignalHandler(TSignalHandler *sh)
Add a signal handler to list of system signal handlers.
Definition: TSystem.cxx:535
virtual void Exit(int code, Bool_t mode=kTRUE)
Exit the application.
Definition: TSystem.cxx:719
virtual const char * HostName()
Return the system's host name.
Definition: TSystem.cxx:306
virtual void Sleep(UInt_t milliSec)
Sleep milliSec milli seconds.
Definition: TSystem.cxx:440
virtual const char * WorkingDirectory()
Return working directory.
Definition: TSystem.cxx:872
virtual char * Which(const char *search, const char *file, EAccessMode mode=kFileExists)
Find location of file in a search path.
Definition: TSystem.cxx:1546
virtual const char * HomeDirectory(const char *userName=nullptr)
Return the user's home directory.
Definition: TSystem.cxx:888
virtual void Abort(int code=0)
Abort the application.
Definition: TSystem.cxx:727
virtual int Unlink(const char *name)
Unlink, i.e.
Definition: TSystem.cxx:1381
virtual void StackTrace()
Print a stack trace.
Definition: TSystem.cxx:735
const char * GetFile() const
Definition: TUrl.h:69
void SetUrl(const char *url, Bool_t defaultIsFile=kFALSE)
Parse url character string and split in its different subcomponents.
Definition: TUrl.cxx:110
TLine * line
const Int_t n
Definition: legend1.C:16
static constexpr double s
Definition: file.py:1
static const char * what
Definition: stlLoader.cc:6
auto * m
Definition: textangle.C:8