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 "Riostream.h"
24
25#ifdef WIN32
26 #include <io.h>
27 typedef long off_t;
28#endif
29#include <stdlib.h>
30#include <errno.h>
31#include <time.h>
32#include <fcntl.h>
33#include <sys/types.h>
34#include <sys/stat.h>
35
36#if (defined(__FreeBSD__) && (__FreeBSD__ < 4)) || \
37 (defined(__APPLE__) && (!defined(MAC_OS_X_VERSION_10_3) || \
38 (MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_3)))
39#include <sys/file.h>
40#define lockf(fd, op, sz) flock((fd), (op))
41#ifndef F_LOCK
42#define F_LOCK (LOCK_EX | LOCK_NB)
43#endif
44#ifndef F_ULOCK
45#define F_ULOCK LOCK_UN
46#endif
47#endif
48
49#include "RRemoteProtocol.h"
50
51#include "TApplicationServer.h"
52#include "TBenchmark.h"
53#include "TEnv.h"
54#include "TError.h"
55#include "TException.h"
56#include "TInterpreter.h"
57#include "TMD5.h"
58#include "TMessage.h"
59#include "TROOT.h"
60#include "TSocket.h"
61#include "TSystem.h"
62#include "TRemoteObject.h"
63#include "TUrl.h"
64#include "TObjString.h"
65#include "compiledata.h"
66#include "TClass.h"
67
68
69//----- Interrupt signal handler -----------------------------------------------
70////////////////////////////////////////////////////////////////////////////////
71
72class TASInterruptHandler : public TSignalHandler {
73 TApplicationServer *fServ;
74public:
75 TASInterruptHandler(TApplicationServer *s)
76 : TSignalHandler(kSigUrgent, kFALSE) { fServ = s; }
77 Bool_t Notify();
78};
79
80////////////////////////////////////////////////////////////////////////////////
81/// Handle this interrupt
82
83Bool_t TASInterruptHandler::Notify()
84{
85 fServ->HandleUrgentData();
86 if (TROOT::Initialized()) {
87 Throw(GetSignal());
88 }
89 return kTRUE;
90}
91
92//----- SigPipe signal handler -------------------------------------------------
93////////////////////////////////////////////////////////////////////////////////
94
95class TASSigPipeHandler : public TSignalHandler {
96 TApplicationServer *fServ;
97public:
98 TASSigPipeHandler(TApplicationServer *s) : TSignalHandler(kSigPipe, kFALSE)
99 { fServ = s; }
100 Bool_t Notify();
101};
102
103////////////////////////////////////////////////////////////////////////////////
104/// Handle this signal
105
106Bool_t TASSigPipeHandler::Notify()
107{
108 fServ->HandleSigPipe();
109 return kTRUE;
110}
111
112//----- Input handler for messages from client -----------------------
113////////////////////////////////////////////////////////////////////////////////
114
115class TASInputHandler : public TFileHandler {
116 TApplicationServer *fServ;
117public:
118 TASInputHandler(TApplicationServer *s, Int_t fd) : TFileHandler(fd, 1)
119 { fServ = s; }
120 Bool_t Notify();
121 Bool_t ReadNotify() { return Notify(); }
122};
123
124////////////////////////////////////////////////////////////////////////////////
125/// Handle this input
126
127Bool_t TASInputHandler::Notify()
128{
129 fServ->HandleSocketInput();
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
351 gSystem->AddSignalHandler(new TASInterruptHandler(this));
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) {
390 char *workdir = gSystem->ExpandPathName(fWorkDir.Data());
391 fWorkDir = workdir;
392 delete [] workdir;
393 }
394
395 // Go to working dir
399 SysError("Setup", "can not change to directory %s",
400 fWorkDir.Data());
401 }
402 } else {
407 SysError("Setup", "can not change to directory %s",
408 fWorkDir.Data());
409 }
410 }
411 }
412
413#if 0 // G.Ganis May 11, 2007
414 // This needs to be fixed: we disable for the time being
415 // Socket options: incoming OOB should generate a SIGURG
416 if (fSocket->SetOption(kProcessGroup, (-1)*gSystem->GetPid()) != 0)
417 SysWarning("Setup", "failed to enable SIGURG generation on incoming OOB");
418#endif
419
420 // Send messages off immediately to reduce latency
421 if (fSocket->SetOption(kNoDelay, 1) != 0) {}
422 //SysWarning("Setup", "failed to set no-delay option on input socket");
423
424 // Check every two hours if client is still alive
425 if (fSocket->SetOption(kKeepAlive, 1) != 0) {}
426 //SysWarning("Setup", "failed to set keepalive option on input socket");
427
428 // Install SigPipe handler to handle kKeepAlive failure
429 gSystem->AddSignalHandler(new TASSigPipeHandler(this));
430
431 // Done
432 return 0;
433}
434
435////////////////////////////////////////////////////////////////////////////////
436/// Cleanup. Not really necessary since after this dtor there is no
437/// live anyway.
438
440{
445}
446
447////////////////////////////////////////////////////////////////////////////////
448/// Get and handle command line options. Fixed format:
449/// "protocol url"
450
451void TApplicationServer::GetOptions(Int_t *argc, char **argv)
452{
453 if (*argc < 4) {
454 Fatal("GetOptions", "must be started with 4 arguments");
455 gSystem->Exit(1);
456 }
457
458 // Protocol run by the client
459 fProtocol = TString(argv[1]).Atoi();
460
461 // Client URL
462 fUrl.SetUrl(argv[2]);
463
464 // Debug level
465 gDebug = 0;
466 TString argdbg(argv[3]);
467 if (argdbg.BeginsWith("-d=")) {
468 argdbg.ReplaceAll("-d=","");
469 gDebug = argdbg.Atoi();
470 }
471}
472
473////////////////////////////////////////////////////////////////////////////////
474/// Main server eventloop.
475
477{
478 // Setup the server
479 if (fIsValid) {
480 // Run the main event loop
481 TApplication::Run(retrn);
482 } else {
483 Error("Run", "invalid instance: cannot Run()");
484 gSystem->Exit(1);
485 }
486}
487
488////////////////////////////////////////////////////////////////////////////////
489/// Handle input coming from the client or from the master server.
490
492{
493 TMessage *mess;
494 char str[2048];
495 Int_t what;
496
497 if (fSocket->Recv(mess) <= 0) {
498 // Pending: do something more intelligent here
499 // but at least get a message in the log file
500 Error("HandleSocketInput", "retrieving message from input socket");
501 Terminate(0);
502 return;
503 }
504
505 what = mess->What();
506 if (gDebug > 0)
507 Info("HandleSocketInput", "got message of type %d", what);
508
509 switch (what) {
510
511 case kMESS_CINT:
513 mess->ReadString(str, sizeof(str));
514 if (gDebug > 1)
515 Info("HandleSocketInput:kMESS_CINT", "processing: %s...", str);
516 ProcessLine(str);
517 }
518 SendCanvases();
519 SendLogFile();
520 break;
521
522 case kMESS_STRING:
523 mess->ReadString(str, sizeof(str));
524 break;
525
526 case kMESS_OBJECT:
527 mess->ReadObject(mess->GetClass());
528 break;
529
530 case kMESS_ANY:
531 {
532 Int_t type;
533 (*mess) >> type;
534 switch (type) {
535 case kRRT_Reset:
536 mess->ReadString(str, sizeof(str));
537 Reset(str);
538 break;
539
540 case kRRT_CheckFile:
541 // Handle file checking request
542 HandleCheckFile(mess);
543 break;
544
545 case kRRT_File:
546 // A file follows
547 mess->ReadString(str, sizeof(str));
548 { char name[2048], i1[20], i2[40];
549 sscanf(str, "%2047s %19s %39s", name, i1, i2);
550 Int_t bin = atoi(i1);
551 Long_t size = atol(i2);
552 ReceiveFile(name, bin ? kTRUE : kFALSE, size);
553 }
554 break;
555
556 case kRRT_Terminate:
557 // Terminate the session (will not return from here)
558 Int_t status;
559 (*mess) >> status;
560 Terminate(status);
561 break;
562
563 default:
564 break;
565 }
566 }
567 SendLogFile();
568 break;
569 default:
570 Warning("HandleSocketInput","message type unknown (%d)", what);
571 SendLogFile();
572 break;
573 }
574
575 delete mess;
576}
577
578////////////////////////////////////////////////////////////////////////////////
579/// Handle Out-Of-Band data sent by the master or client.
580
582{
583 char oob_byte;
584 Int_t n, nch, wasted = 0;
585
586 const Int_t kBufSize = 1024;
587 char waste[kBufSize];
588
589 // Real-time notification of messages
591
592 Info("HandleUrgentData", "handling oob...");
593
594 // Receive the OOB byte
595 while ((n = fSocket->RecvRaw(&oob_byte, 1, kOob)) < 0) {
596 if (n == -2) { // EWOULDBLOCK
597 //
598 // The OOB data has not yet arrived: flush the input stream
599 //
600 // In some systems (Solaris) regular recv() does not return upon
601 // receipt of the oob byte, which makes the below call to recv()
602 // block indefinitely if there are no other data in the queue.
603 // FIONREAD ioctl can be used to check if there are actually any
604 // data to be flushed. If not, wait for a while for the oob byte
605 // to arrive and try to read it again.
606 //
608 if (nch == 0) {
609 gSystem->Sleep(1000);
610 continue;
611 }
612
613 if (nch > kBufSize) nch = kBufSize;
614 n = fSocket->RecvRaw(waste, nch);
615 if (n <= 0) {
616 Error("HandleUrgentData", "error receiving waste");
617 break;
618 }
619 wasted = 1;
620 } else {
621 Error("HandleUrgentData", "error receiving OOB (n = %d)",n);
622 return;
623 }
624 }
625
626 Info("HandleUrgentData", "got OOB byte: %d\n", oob_byte);
627
628 switch (oob_byte) {
629
630 case kRRI_Hard:
631 Info("HandleUrgentData", "*** Hard Interrupt");
632
633 // Flush input socket
634 while (1) {
635 Int_t atmark;
636
637 fSocket->GetOption(kAtMark, atmark);
638
639 if (atmark) {
640 // Send the OOB byte back so that the client knows where
641 // to stop flushing its input stream of obsolete messages
642 n = fSocket->SendRaw(&oob_byte, 1, kOob);
643 if (n <= 0)
644 Error("HandleUrgentData", "error sending OOB");
645 break;
646 }
647
648 // find out number of bytes to read before atmark
650 if (nch == 0) {
651 gSystem->Sleep(1000);
652 continue;
653 }
654
655 if (nch > kBufSize) nch = kBufSize;
656 n = fSocket->RecvRaw(waste, nch);
657 if (n <= 0) {
658 Error("HandleUrgentData", "error receiving waste (2)");
659 break;
660 }
661 }
662
663 SendLogFile();
664
665 break;
666
667 case kRRI_Soft:
668 Info("HandleUrgentData", "Soft Interrupt");
669
670 if (wasted) {
671 Error("HandleUrgentData", "soft interrupt flushed stream");
672 break;
673 }
674
675 Interrupt();
676
677 SendLogFile();
678
679 break;
680
681 case kRRI_Shutdown:
682 Info("HandleUrgentData", "Shutdown Interrupt");
683
684 Terminate(0);
685
686 break;
687
688 default:
689 Error("HandleUrgentData", "unexpected OOB byte");
690 break;
691 }
692}
693
694////////////////////////////////////////////////////////////////////////////////
695/// Called when the client is not alive anymore (i.e. when kKeepAlive
696/// has failed).
697
699{
700 // Real-time notification of messages
702
703 Info("HandleSigPipe", "client died");
704 Terminate(0); // will not return from here....
705}
706
707////////////////////////////////////////////////////////////////////////////////
708/// Reset environment to be ready for execution of next command.
709
710void TApplicationServer::Reset(const char *dir)
711{
712 // First go to new directory.
713 gDirectory->cd(dir);
714
715 // Clear interpreter environment.
716 gROOT->Reset();
717
718 // Make sure current directory is empty (don't delete anything when
719 // we happen to be in the ROOT memory only directory!?)
720 if (gDirectory != gROOT) {
721 gDirectory->Delete();
722 }
723}
724
725////////////////////////////////////////////////////////////////////////////////
726/// Receive a file, either sent by a client or a master server.
727/// If bin is true it is a binary file, other wise it is an ASCII
728/// file and we need to check for Windows \r tokens. Returns -1 in
729/// case of error, 0 otherwise.
730
732{
733 if (size <= 0) return 0;
734
735 // open file, overwrite already existing file
736 Int_t fd = open(file, O_CREAT | O_TRUNC | O_WRONLY, 0600);
737 if (fd < 0) {
738 SysError("ReceiveFile", "error opening file %s", file);
739 return -1;
740 }
741
742 const Int_t kMAXBUF = 16384; //32768 //16384 //65536;
743 char buf[kMAXBUF], cpy[kMAXBUF];
744
745 Int_t left, r;
746 Long64_t filesize = 0;
747
748 while (filesize < size) {
749 left = Int_t(size - filesize);
750 if (left > kMAXBUF)
751 left = kMAXBUF;
752 r = fSocket->RecvRaw(&buf, left);
753 if (r > 0) {
754 char *p = buf;
755
756 filesize += r;
757 while (r) {
758 Int_t w;
759
760 if (!bin) {
761 Int_t k = 0, i = 0, j = 0;
762 char *q;
763 while (i < r) {
764 if (p[i] == '\r') {
765 i++;
766 k++;
767 }
768 cpy[j++] = buf[i++];
769 }
770 q = cpy;
771 r -= k;
772 w = write(fd, q, r);
773 } else {
774 w = write(fd, p, r);
775 }
776
777 if (w < 0) {
778 SysError("ReceiveFile", "error writing to file %s", file);
779 close(fd);
780 return -1;
781 }
782 r -= w;
783 p += w;
784 }
785 } else if (r < 0) {
786 Error("ReceiveFile", "error during receiving file %s", file);
787 close(fd);
788 return -1;
789 }
790 }
791
792 close(fd);
793
794 chmod(file, 0644);
795
796 return 0;
797}
798
799////////////////////////////////////////////////////////////////////////////////
800/// Send log file to master.
801/// If start > -1 send only bytes in the range from start to end,
802/// if end <= start send everything from start.
803
805{
806 // Determine the number of bytes left to be read from the log file.
807 fflush(stdout);
808
809 off_t ltot=0, lnow=0;
810 Int_t left = -1;
811 Bool_t adhoc = kFALSE;
812
813 if (fLogFileDes > -1) {
814 ltot = lseek(fileno(stdout), (off_t) 0, SEEK_END);
815 lnow = lseek(fLogFileDes, (off_t) 0, SEEK_CUR);
816 if (lnow == -1) {
817 SysError("SendLogFile", "lseek failed");
818 lnow = 0;
819 }
820
821 if (start > -1) {
822 lseek(fLogFileDes, (off_t) start, SEEK_SET);
823 if (end <= start || end > ltot)
824 end = ltot;
825 left = (Int_t)(end - start);
826 if (end < ltot)
827 left++;
828 adhoc = kTRUE;
829 } else {
830 left = (Int_t)(ltot - lnow);
831 }
832 }
833
835
836 if (left > 0) {
837
838 m << (Int_t)kRRT_LogFile << left;
839 fSocket->Send(m);
840
841 const Int_t kMAXBUF = 32768; //16384 //65536;
842 char buf[kMAXBUF];
843 Int_t wanted = (left > kMAXBUF) ? kMAXBUF : left;
844 Int_t len;
845 do {
846 while ((len = read(fLogFileDes, buf, wanted)) < 0 &&
847 TSystem::GetErrno() == EINTR)
849
850 if (len < 0) {
851 SysError("SendLogFile", "error reading log file");
852 break;
853 }
854
855 if (end == ltot && len == wanted)
856 buf[len-1] = '\n';
857
858 if (fSocket->SendRaw(buf, len) < 0) {
859 SysError("SendLogFile", "error sending log file");
860 break;
861 }
862
863 // Update counters
864 left -= len;
865 wanted = (left > kMAXBUF) ? kMAXBUF : left;
866
867 } while (len > 0 && left > 0);
868 }
869
870 // Restore initial position if partial send
871 if (adhoc)
872 lseek(fLogFileDes, lnow, SEEK_SET);
873
874 m.Reset();
875 m << (Int_t)kRRT_LogDone << status;
876
877 fSocket->Send(m);
878}
879
880////////////////////////////////////////////////////////////////////////////////
881/// Send any created canvas to client
882
884{
885 Int_t nc = 0;
886
887 // Send back new canvases
889 TIter next(gROOT->GetListOfCanvases());
890 TObject *o = 0;
891 while ((o = next())) {
892 if (!fSentCanvases)
893 fSentCanvases = new TList;
894 Bool_t sentalready = kFALSE;
895 // We cannot use FindObject here because there may be invalid
896 // objects in the send list (i.e. deleted canvases)
898 while (lnk) {
899 TObject *sc = lnk->GetObject();
900 lnk = lnk->Next();
901 if ((sc->TestBit(kNotDeleted)) && sc == o)
902 sentalready = kTRUE;
903 }
904 if (!sentalready) {
905 if (gDebug > 0)
906 Info("SendCanvases","new canvas found: %p", o);
907 mess.Reset(kMESS_OBJECT);
908 mess.WriteObject(o);
909 fSocket->Send(mess);
910 nc++;
911 fSentCanvases->Add(o);
912 }
913 }
914 return nc;
915}
916
917////////////////////////////////////////////////////////////////////////////////
918/// Browse directory and send back its content to client.
919
921{
922 Int_t nc = 0;
923
925 if (!fWorkingDir || !dirname || !*dirname) {
926 if (!fWorkingDir)
927 fWorkingDir = new TRemoteObject(fWorkDir, fWorkDir, "TSystemDirectory");
929 mess.Reset(kMESS_OBJECT);
931 fSocket->Send(mess);
932 nc++;
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 }
942 return nc;
943}
944
945////////////////////////////////////////////////////////////////////////////////
946/// Browse root file and send back its content;
947/// if fname is null, send the full list of files.
948
950{
951 Int_t nc = 0;
952
953 TList *list = new TList;
955 if (!fname || !*fname) {
956 // fname is null, so send the list of files.
957 TIter next(gROOT->GetListOfFiles());
958 TNamed *fh = 0;
959 TRemoteObject *robj;
960 while ((fh = (TNamed *)next())) {
961 robj = new TRemoteObject(fh->GetName(), fh->GetTitle(), "TFile");
962 list->Add(robj);
963 }
964 if (list->GetEntries() > 0) {
965 mess.Reset(kMESS_OBJECT);
966 mess.WriteObject(list);
967 fSocket->Send(mess);
968 nc++;
969 }
970 }
971 else {
972 // get Root file content and send the list of objects
973 TDirectory *fh = (TDirectory *)gROOT->GetListOfFiles()->FindObject(fname);
974 if (fh) {
975 fh->cd();
976 TRemoteObject dir(fh->GetName(), fh->GetTitle(), "TFile");
977 TList *keylist = (TList *)gROOT->ProcessLine(Form("((TFile *)0x%lx)->GetListOfKeys();", (ULong_t)fh));
978 TIter nextk(keylist);
979 TNamed *key = 0;
980 TRemoteObject *robj;
981 while ((key = (TNamed *)nextk())) {
982 robj = new TRemoteObject(key->GetName(), key->GetTitle(), "TKey");
983 const char *classname = (const char *)gROOT->ProcessLine(Form("((TKey *)0x%lx)->GetClassName();", (ULong_t)key));
984 robj->SetKeyClassName(classname);
985 Bool_t isFolder = (Bool_t)gROOT->ProcessLine(Form("((TKey *)0x%lx)->IsFolder();", (ULong_t)key));
986 robj->SetFolder(isFolder);
987 robj->SetRemoteAddress((Long_t) key);
988 list->Add(robj);
989 }
990 if (list->GetEntries() > 0) {
991 mess.Reset(kMESS_OBJECT);
992 mess.WriteObject(list);
993 fSocket->Send(mess);
994 nc++;
995 }
996 }
997 }
998 return nc;
999}
1000
1001////////////////////////////////////////////////////////////////////////////////
1002/// Read key object and send it back to client.
1003
1005{
1006 Int_t nc = 0;
1007
1008 TMessage mess(kMESS_OBJECT);
1009 TNamed *obj = (TNamed *)gROOT->ProcessLine(Form("gFile->GetKey(\"%s\")->ReadObj();", keyname));
1010 if (obj) {
1011 mess.Reset(kMESS_OBJECT);
1012 mess.WriteObject(obj);
1013 fSocket->Send(mess);
1014 nc++;
1015 }
1016 return nc;
1017}
1018
1019////////////////////////////////////////////////////////////////////////////////
1020/// Terminate the proof server.
1021
1023{
1024 // Close and remove the log file; remove the cleanup script
1025 if (fLogFile) {
1026 fclose(fLogFile);
1027 // Delete the log file unless we are in debug mode
1028 if (gDebug <= 0)
1030 TString cleanup = fLogFilePath;
1031 cleanup.ReplaceAll(".log", ".cleanup");
1032 gSystem->Unlink(cleanup);
1033 }
1034
1035 // Remove input handler to avoid spurious signals in socket
1036 // selection for closing activities executed upon exit()
1038 TObject *fh = 0;
1039 while ((fh = next())) {
1040 TASInputHandler *ih = dynamic_cast<TASInputHandler *>(fh);
1041 if (ih)
1043 }
1044
1045 // Stop processing events
1046 gSystem->Exit(status);
1047}
1048
1049////////////////////////////////////////////////////////////////////////////////
1050/// Handle file checking request.
1051
1053{
1054 TString filenam;
1055 TMD5 md5;
1057
1058 // Parse message
1059 (*mess) >> filenam >> md5;
1060
1061 // check file in working directory
1062 TMD5 *md5local = TMD5::FileChecksum(filenam);
1063 if (md5local && md5 == (*md5local)) {
1064 // We have an updated copy of the file
1065 m << (Int_t) kRRT_CheckFile << (Bool_t) kTRUE;
1066 fSocket->Send(m);
1067 if (gDebug > 0)
1068 Info("HandleCheckFile", "up-to-date version of %s available", filenam.Data());
1069 } else {
1071 fSocket->Send(m);
1072 if (gDebug > 0)
1073 Info("HandleCheckFile", "file %s needs to be uploaded", filenam.Data());
1074 }
1075 delete md5local;
1076}
1077
1078////////////////////////////////////////////////////////////////////////////////
1079/// The error handler function. It prints the message on stderr and
1080/// if abort is set it aborts the application.
1081
1082void TApplicationServer::ErrorHandler(Int_t level, Bool_t abort, const char *location,
1083 const char *msg)
1084{
1085 if (gErrorIgnoreLevel == kUnset) {
1087 if (gEnv) {
1088 TString slevel = gEnv->GetValue("Root.ErrorIgnoreLevel", "Print");
1089 if (!slevel.CompareTo("Print", TString::kIgnoreCase))
1091 else if (!slevel.CompareTo("Info", TString::kIgnoreCase))
1093 else if (!slevel.CompareTo("Warning", TString::kIgnoreCase))
1095 else if (!slevel.CompareTo("Error", TString::kIgnoreCase))
1097 else if (!slevel.CompareTo("Break", TString::kIgnoreCase))
1099 else if (!slevel.CompareTo("SysError", TString::kIgnoreCase))
1101 else if (!slevel.CompareTo("Fatal", TString::kIgnoreCase))
1103 }
1104 }
1105
1106 if (level < gErrorIgnoreLevel)
1107 return;
1108
1109 static TString syslogService;
1110
1111 if (syslogService.IsNull()) {
1112 syslogService = "server";
1113 gSystem->Openlog(syslogService, kLogPid | kLogCons, kLogLocal5);
1114 }
1115
1116 const char *type = 0;
1117 ELogLevel loglevel = kLogInfo;
1118
1119 if (level >= kPrint) {
1120 loglevel = kLogInfo;
1121 type = "Print";
1122 }
1123 if (level >= kInfo) {
1124 loglevel = kLogInfo;
1125 type = "Info";
1126 }
1127 if (level >= kWarning) {
1128 loglevel = kLogWarning;
1129 type = "Warning";
1130 }
1131 if (level >= kError) {
1132 loglevel = kLogErr;
1133 type = "Error";
1134 }
1135 if (level >= kBreak) {
1136 loglevel = kLogErr;
1137 type = "*** Break ***";
1138 }
1139 if (level >= kSysError) {
1140 loglevel = kLogErr;
1141 type = "SysError";
1142 }
1143 if (level >= kFatal) {
1144 loglevel = kLogErr;
1145 type = "Fatal";
1146 }
1147
1148 TString node = "server";
1149 TString buf;
1150
1151 if (!location || !location[0] ||
1152 (level >= kPrint && level < kInfo) ||
1153 (level >= kBreak && level < kSysError)) {
1154 fprintf(stderr, "%s on %s: %s\n", type, node.Data(), msg);
1155 buf.Form("%s:%s:%s", node.Data(), type, msg);
1156 } else {
1157 fprintf(stderr, "%s in <%s> on %s: %s\n", type, location, node.Data(), msg);
1158 buf.Form("%s:%s:<%s>:%s", node.Data(), type, location, msg);
1159 }
1160 fflush(stderr);
1161
1162 gSystem->Syslog(loglevel, buf);
1163
1164 if (abort) {
1165 fprintf(stderr, "aborting\n");
1166 fflush(stderr);
1168 gSystem->Abort();
1169 }
1170}
1171
1172////////////////////////////////////////////////////////////////////////////////
1173/// Parse a command line received from the client, making sure that the files
1174/// needed for the execution, if any, are available. The line is either a C++
1175/// statement or an interpreter command starting with a ".".
1176/// Return the return value of the command casted to a long.
1177
1179{
1180 if (!line || !*line) return 0;
1181
1182 // If load or execute request we must make sure that we have the files.
1183 // If not we ask the client to send them, blocking until we have everything.
1184 if (!strncmp(line, ".L", 2) || !strncmp(line, ".U", 2) ||
1185 !strncmp(line, ".X", 2) || !strncmp(line, ".x", 2)) {
1186 TString aclicMode;
1187 TString arguments;
1188 TString io;
1189 TString fname = gSystem->SplitAclicMode(line+3, aclicMode, arguments, io);
1190
1191 char *imp = gSystem->Which(TROOT::GetMacroPath(), fname, kReadPermission);
1192 if (!imp) {
1193
1194 // Make sure that we can write in the directory where we are
1196 Error("ProcessLine","no write permission in %s", gSystem->WorkingDirectory());
1197 return 0;
1198 }
1199
1200 if (gDebug > 0)
1201 Info("ProcessLine", "macro %s not found in path %s: asking the client",
1202 fname.Data(), TROOT::GetMacroPath());
1204 m << (Int_t) kRRT_SendFile << TString(gSystem->BaseName(fname));
1205 fSocket->Send(m);
1206
1207 // Wait for the reply(ies)
1208 Int_t type;
1209 Bool_t filefollows = kTRUE;
1210
1211 while (filefollows) {
1212
1213 // Get a message
1214 TMessage *rm = 0;
1215 if (fSocket->Recv(rm) <= 0) {
1216 Error("ProcessLine","ask-file: received empty message from client");
1217 return 0;
1218 }
1219 if (rm->What() != kMESS_ANY) {
1220 Error("ProcessLine","ask-file: wrong message received (what: %d)", rm->What());
1221 return 0;
1222 }
1223 (*rm) >> type;
1224 if (type != kRRT_SendFile) {
1225 Error("ProcessLine","ask-file: wrong sub-type received (type: %d)", type);
1226 return 0;
1227 }
1228 (*rm) >> filefollows;
1229 if (filefollows) {
1230 // Read the file specifications
1231 if (fSocket->Recv(rm) <= 0) {
1232 Error("ProcessLine","file: received empty message from client");
1233 return 0;
1234 }
1235 if (rm->What() != kMESS_ANY) {
1236 Error("ProcessLine","file: wrong message received (what: %d)", rm->What());
1237 return 0;
1238 }
1239 (*rm) >> type;
1240 if (type != kRRT_File) {
1241 Error("ProcessLine","file: wrong sub-type received (type: %d)", type);
1242 return 0;
1243 }
1244 // A file follows
1245 char str[2048];
1246 rm->ReadString(str, sizeof(str));
1247 char name[2048], i1[20], i2[40];
1248 sscanf(str, "%2047s %19s %39s", name, i1, i2);
1249 Int_t bin = atoi(i1);
1250 Long_t size = atol(i2);
1251 ReceiveFile(name, bin ? kTRUE : kFALSE, size);
1252 }
1253 }
1254 }
1255 delete [] imp;
1256 }
1257
1258 // Process the line now
1260}
1261
1262////////////////////////////////////////////////////////////////////////////////
1263/// Execute logon macro's. There are three levels of logon macros that
1264/// will be executed: the system logon etc/system.rootlogon.C, the global
1265/// user logon ~/.rootlogon.C and the local ./.rootlogon.C. For backward
1266/// compatibility also the logon macro as specified by the Rint.Logon
1267/// environment setting, by default ./rootlogon.C, will be executed.
1268/// No logon macros will be executed when the system is started with
1269/// the -n option.
1270
1272{
1273 if (NoLogOpt()) return;
1274
1275 TString name = ".rootlogon.C";
1276 TString sname = "system";
1277 sname += name;
1278 char *s = gSystem->ConcatFileName(TROOT::GetEtcDir(), sname);
1280 ProcessFile(s);
1281 }
1282 delete [] s;
1285 ProcessFile(s);
1286 }
1287 delete [] s;
1288 // avoid executing ~/.rootlogon.C twice
1289 if (strcmp(gSystem->HomeDirectory(), gSystem->WorkingDirectory())) {
1292 }
1293
1294 // execute also the logon macro specified by "Rint.Logon"
1295 const char *logon = gEnv->GetValue("Rint.Logon", (char*)0);
1296 if (logon) {
1297 char *mac = gSystem->Which(TROOT::GetMacroPath(), logon, kReadPermission);
1298 if (mac)
1299 ProcessFile(logon);
1300 delete [] mac;
1301 }
1302}
@ 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:550
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
int Int_t
Definition: RtypesCore.h:41
const Bool_t kFALSE
Definition: RtypesCore.h:88
unsigned long ULong_t
Definition: RtypesCore.h:51
long Long_t
Definition: RtypesCore.h:50
bool Bool_t
Definition: RtypesCore.h:59
long long Long64_t
Definition: RtypesCore.h:69
const Bool_t kTRUE
Definition: RtypesCore.h:87
#define ClassImp(name)
Definition: Rtypes.h:365
R__EXTERN Int_t gDebug
Definition: Rtypes.h:91
R__EXTERN TBenchmark * gBenchmark
Definition: TBenchmark.h:59
#define gDirectory
Definition: TDirectory.h:223
R__EXTERN TEnv * gEnv
Definition: TEnv.h:171
const Int_t kPrint
Definition: TError.h:36
const Int_t kError
Definition: TError.h:39
const Int_t kSysError
Definition: TError.h:41
const Int_t kUnset
Definition: TError.h:35
const Int_t kFatal
Definition: TError.h:42
void Error(const char *location, const char *msgfmt,...)
const Int_t kBreak
Definition: TError.h:40
R__EXTERN Int_t gErrorAbortLevel
Definition: TError.h:106
const Int_t kWarning
Definition: TError.h:38
R__EXTERN Int_t gErrorIgnoreLevel
Definition: TError.h:105
ErrorHandlerFunc_t SetErrorHandler(ErrorHandlerFunc_t newhandler)
Set an errorhandler function. Returns the old handler.
Definition: TError.cxx:106
const Int_t kInfo
Definition: TError.h:37
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:109
int type
Definition: TGX11.cxx:120
float * q
Definition: THbookFile.cxx:87
#define gInterpreter
Definition: TInterpreter.h:555
#define gROOT
Definition: TROOT.h:415
char * Form(const char *fmt,...)
@ kSigPipe
@ kSigUrgent
@ kKeepAlive
Definition: TSystem.h:221
@ kBytesToRead
Definition: TSystem.h:227
@ kNoDelay
Definition: TSystem.h:223
@ kProcessGroup
Definition: TSystem.h:225
@ kAtMark
Definition: TSystem.h:226
@ kOob
Definition: TSystem.h:232
@ kReadPermission
Definition: TSystem.h:48
@ kWritePermission
Definition: TSystem.h:47
@ kLogLocal5
Definition: TSystem.h:73
ELogLevel
Definition: TSystem.h:56
@ kLogWarning
Definition: TSystem.h:61
@ kLogInfo
Definition: TSystem.h:63
@ kLogErr
Definition: TSystem.h:60
R__EXTERN TSystem * gSystem
Definition: TSystem.h:560
@ kLogPid
Definition: TSystem.h:52
@ kLogCons
Definition: TSystem.h:53
#define snprintf
Definition: civetweb.c:1540
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.
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.
Long_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,...
void HandleCheckFile(TMessage *mess)
Handle file checking request.
virtual ~TApplicationServer()
Cleanup.
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 void Run(Bool_t retrn=kFALSE)
Main application eventloop. Calls system dependent eventloop via gSystem.
Bool_t NoLogOpt() const
Definition: TApplication.h:139
virtual Long_t ProcessLine(const char *line, Bool_t sync=kFALSE, Int_t *error=0)
Process a single command line, either a C++ statement or an interpreter command starting with a "....
virtual Long_t ProcessFile(const char *file, Int_t *error=0, Bool_t keep=kFALSE)
Process a file containing a C++ macro.
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:177
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:34
virtual Bool_t cd(const char *path=nullptr)
Change current directory to "this" directory.
Definition: TDirectory.cxx:497
virtual Int_t GetValue(const char *name, Int_t dflt) const
Returns the integer value for a resource.
Definition: TEnv.cxx:491
virtual Bool_t Notify()
Notify when event occurred on descriptor associated with this handler.
void SetFd(int fd)
virtual Bool_t ReadNotify()
Notify when something can be read from the descriptor associated with this handler.
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
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:172
@ 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:894
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition: TObject.cxx:866
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
Definition: TObject.cxx:694
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition: TObject.cxx:880
virtual void Fatal(const char *method, const char *msgfmt,...) const
Issue fatal error message.
Definition: TObject.cxx:908
void ResetBit(UInt_t f)
Definition: TObject.h:171
virtual void Info(const char *method, const char *msgfmt,...) const
Issue info message.
Definition: TObject.cxx:854
static const char * GetMacroPath()
Get macro search path. Static utility function.
Definition: TROOT.cxx:2741
static Bool_t Initialized()
Return kTRUE if the TROOT object has been initialized.
Definition: TROOT.cxx:2844
static const TString & GetEtcDir()
Get the sysconfig directory in the installation. Static utility function.
Definition: TROOT.cxx:2987
The TRemoteObject class provides protocol for browsing ROOT objects from a remote ROOT session.
Definition: TRemoteObject.h:36
void SetKeyClassName(const char *name)
Definition: TRemoteObject.h:61
void SetRemoteAddress(Long_t addr)
Definition: TRemoteObject.h:62
virtual void Browse(TBrowser *b)
Browse remote object.
void SetFolder(Bool_t isFolder)
Definition: TRemoteObject.h:59
virtual Bool_t Notify()
Notify when signal occurs.
Option_t * GetOption() const
Definition: TSocket.h:98
virtual Int_t SetOption(ESockOptions opt, Int_t val)
Set socket options.
Definition: TSocket.cxx:1011
virtual Int_t Recv(TMessage *&mess)
Receive a TMessage object.
Definition: TSocket.cxx:816
virtual Int_t RecvRaw(void *buffer, Int_t length, ESendRecvOptions opt=kDefault)
Receive a raw buffer of specified length bytes.
Definition: TSocket.cxx:896
virtual Int_t SendRaw(const void *buffer, Int_t length, ESendRecvOptions opt=kDefault)
Send a raw buffer of specified length.
Definition: TSocket.cxx:619
virtual Int_t GetDescriptor() const
Definition: TSocket.h:112
virtual Int_t Send(const TMessage &mess)
Send a TMessage object.
Definition: TSocket.cxx:521
Basic string class.
Definition: TString.h:131
Ssiz_t Length() const
Definition: TString.h:405
int CompareTo(const char *cs, ECaseCompare cmp=kExact) const
Compare a string to char *cs2.
Definition: TString.cxx:418
Int_t Atoi() const
Return integer value of string.
Definition: TString.cxx:1921
const char * Data() const
Definition: TString.h:364
TString & ReplaceAll(const TString &s1, const TString &s2)
Definition: TString.h:687
@ kIgnoreCase
Definition: TString.h:263
Bool_t BeginsWith(const char *s, ECaseCompare cmp=kExact) const
Definition: TString.h:610
Bool_t IsNull() const
Definition: TString.h:402
void Form(const char *fmt,...)
Formats a string using a printf style format descriptor.
Definition: TString.cxx:2289
virtual void AddFileHandler(TFileHandler *fh)
Add a file handler to the list of system file handlers.
Definition: TSystem.cxx:564
virtual void Syslog(ELogLevel level, const char *mess)
Send mess to syslog daemon.
Definition: TSystem.cxx:1674
static void ResetErrno()
Static function resetting system error number.
Definition: TSystem.cxx:286
virtual Bool_t ExpandPathName(TString &path)
Expand a pathname getting rid of special shell characters like ~.
Definition: TSystem.cxx:1265
virtual void Openlog(const char *name, Int_t options, ELogFacility facility)
Open connection to system log daemon.
Definition: TSystem.cxx:1665
static Int_t GetErrno()
Static function returning system error number.
Definition: TSystem.cxx:270
virtual int GetPid()
Get process id.
Definition: TSystem.cxx:717
virtual TString SplitAclicMode(const char *filename, TString &mode, TString &args, TString &io) const
This method split a filename of the form:
Definition: TSystem.cxx:4232
virtual char * ConcatFileName(const char *dir, const char *name)
Concatenate a directory and a file name. User must delete returned string.
Definition: TSystem.cxx:1062
virtual int mkdir(const char *name, Bool_t recursive=kFALSE)
Make a file system directory.
Definition: TSystem.cxx:914
virtual const char * HomeDirectory(const char *userName=0)
Return the user's home directory.
Definition: TSystem.cxx:895
virtual TFileHandler * RemoveFileHandler(TFileHandler *fh)
Remove a file handler from the list of file handlers.
Definition: TSystem.cxx:574
virtual TSeqCollection * GetListOfFileHandlers() const
Definition: TSystem.h:384
virtual FILE * OpenPipe(const char *command, const char *mode)
Open a pipe.
Definition: TSystem.cxx:672
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:1287
virtual Bool_t ChangeDirectory(const char *path)
Change directory.
Definition: TSystem.cxx:870
virtual int ClosePipe(FILE *pipe)
Close the pipe.
Definition: TSystem.cxx:681
virtual const char * BaseName(const char *pathname)
Base name of a file name. Base name of /user/root is root.
Definition: TSystem.cxx:942
virtual void AddSignalHandler(TSignalHandler *sh)
Add a signal handler to list of system signal handlers.
Definition: TSystem.cxx:542
virtual void Exit(int code, Bool_t mode=kTRUE)
Exit the application.
Definition: TSystem.cxx:726
virtual const char * HostName()
Return the system's host name.
Definition: TSystem.cxx:313
virtual void Sleep(UInt_t milliSec)
Sleep milliSec milli seconds.
Definition: TSystem.cxx:447
virtual const char * WorkingDirectory()
Return working directory.
Definition: TSystem.cxx:879
virtual char * Which(const char *search, const char *file, EAccessMode mode=kFileExists)
Find location of file in a search path.
Definition: TSystem.cxx:1537
virtual void Abort(int code=0)
Abort the application.
Definition: TSystem.cxx:734
virtual int Unlink(const char *name)
Unlink, i.e.
Definition: TSystem.cxx:1372
virtual void StackTrace()
Print a stack trace.
Definition: TSystem.cxx:742
const char * GetFile() const
Definition: TUrl.h:71
void SetUrl(const char *url, Bool_t defaultIsFile=kFALSE)
Parse url character string and split in its different subcomponents.
Definition: TUrl.cxx:108
TLine * line
const Int_t n
Definition: legend1.C:16
static constexpr double s
Definition: file.py:1
auto * m
Definition: textangle.C:8