Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
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
24#include <cstdio>
25#include <iostream>
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#define ROOT_compiledata_cxx
66#include "compiledata.h"
67#include "TClass.h"
68
69
70//----- Interrupt signal handler -----------------------------------------------
71////////////////////////////////////////////////////////////////////////////////
72
80
81////////////////////////////////////////////////////////////////////////////////
82/// Handle this interrupt
83
92
93//----- SigPipe signal handler -------------------------------------------------
94////////////////////////////////////////////////////////////////////////////////
95
103
104////////////////////////////////////////////////////////////////////////////////
105/// Handle this signal
106
112
113//----- Input handler for messages from client -----------------------
114////////////////////////////////////////////////////////////////////////////////
115
118public:
121 Bool_t Notify() override;
122 Bool_t ReadNotify() override { return Notify(); }
123};
124
125////////////////////////////////////////////////////////////////////////////////
126/// Handle this input
127
133
134TString TASLogHandler::fgPfx = ""; // Default prefix to be prepended to messages
135////////////////////////////////////////////////////////////////////////////////
136/// Execute 'cmd' in a pipe and handle output messages from the related file
137
138TASLogHandler::TASLogHandler(const char *cmd, TSocket *s, const char *pfx)
139 : TFileHandler(-1, 1), fSocket(s), fPfx(pfx)
140{
142 fFile = 0;
143 if (s && cmd) {
144 fFile = gSystem->OpenPipe(cmd, "r");
145 if (fFile) {
147 // Notify what already in the file
148 Notify();
149 // Used in the destructor
151 } else {
152 fSocket = 0;
153 Error("TASLogHandler", "executing command in pipe");
154 }
155 } else {
156 Error("TASLogHandler",
157 "undefined command (%p) or socket (%p)", (int *)cmd, s);
158 }
159}
160////////////////////////////////////////////////////////////////////////////////
161/// Handle available message from the open file 'f'
162
164 : TFileHandler(-1, 1), fSocket(s), fPfx(pfx)
165{
167 fFile = 0;
168 if (s && f) {
169 fFile = f;
171 // Notify what already in the file
172 Notify();
173 } else {
174 Error("TASLogHandler", "undefined file (%p) or socket (%p)", f, s);
175 }
176}
177////////////////////////////////////////////////////////////////////////////////
178/// Handle available message in the open file
179
188////////////////////////////////////////////////////////////////////////////////
189/// Handle available message in the open file
190
192{
193 if (IsValid()) {
195 // Read buffer
196 char line[4096];
197 char *plf = 0;
198 while (fgets(line, sizeof(line), fFile)) {
199 if ((plf = strchr(line, '\n')))
200 *plf = 0;
201 // Send the message one level up
202 m.Reset(kMESS_ANY);
203 m << (Int_t)kRRT_Message;
204 if (fPfx.Length() > 0) {
205 // Prepend prefix specific to this instance
206 m << TString(Form("%s: %s", fPfx.Data(), line));
207 } else if (fgPfx.Length() > 0) {
208 // Prepend default prefix
209 m << TString(Form("%s: %s", fgPfx.Data(), line));
210 } else {
211 // Nothing to prepend
212 m << TString(line);
213 }
214 fSocket->Send(m);
215 }
216 }
217 return kTRUE;
218}
219////////////////////////////////////////////////////////////////////////////////
220/// Static method to set the default prefix
221
223{
224 fgPfx = pfx;
225}
226
227////////////////////////////////////////////////////////////////////////////////
228/// Init a guard for executing a command in a pipe
229
231 const char *pfx, Bool_t on)
232{
233 fExecHandler = 0;
234 if (cmd && on) {
236 if (fExecHandler->IsValid()) {
238 } else {
239 Error("TASLogHandlerGuard","invalid handler");
240 }
241 } else {
242 if (on)
243 Error("TASLogHandlerGuard","undefined command");
244 }
245}
246
247////////////////////////////////////////////////////////////////////////////////
248/// Init a guard for executing a command in a pipe
249
251 const char *pfx, Bool_t on)
252{
253 fExecHandler = 0;
254 if (f && on) {
255 fExecHandler = new TASLogHandler(f, s, pfx);
256 if (fExecHandler->IsValid()) {
258 } else {
259 Error("TASLogHandlerGuard","invalid handler");
260 }
261 } else {
262 if (on)
263 Error("TASLogHandlerGuard","undefined file");
264 }
265}
266
267////////////////////////////////////////////////////////////////////////////////
268/// Close a guard for executing a command in a pipe
269
277
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
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 }
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) {
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
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
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
444
445////////////////////////////////////////////////////////////////////////////////
446/// Get and handle command line options. Fixed format:
447/// "protocol url"
448
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
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
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);
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;
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) {
634
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;
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];
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 j = 0;
760 for (Int_t i = 0; i < r; ++i) {
761 if (p[i] != '\r') {
762 p[j++] = p[i];
763 }
764 }
765 w = write(fd, p, j);
766 } else {
767 w = write(fd, p, r);
768 }
769
770 if (w < 0) {
771 SysError("ReceiveFile", "error writing to file %s", file);
772 close(fd);
773 return -1;
774 }
775 r -= w;
776 p += w;
777 }
778 } else if (r < 0) {
779 Error("ReceiveFile", "error during receiving file %s", file);
780 close(fd);
781 return -1;
782 }
783 }
784
785 close(fd);
786
787 chmod(file, 0666);
788
789 return 0;
790}
791
792////////////////////////////////////////////////////////////////////////////////
793/// Send log file to master.
794/// If start > -1 send only bytes in the range from start to end,
795/// if end <= start send everything from start.
796
798{
799 // Determine the number of bytes left to be read from the log file.
800 fflush(stdout);
801
802 off_t ltot=0, lnow=0;
803 Int_t left = -1;
805
806 if (fLogFileDes > -1) {
809 if (lnow == -1) {
810 SysError("SendLogFile", "lseek failed");
811 lnow = 0;
812 }
813
814 if (start > -1) {
815 lseek(fLogFileDes, (off_t) start, SEEK_SET);
817 end = ltot;
818 left = (Int_t)(end - start);
819 if (end < ltot)
820 left++;
821 adhoc = kTRUE;
822 } else {
823 left = (Int_t)(ltot - lnow);
824 }
825 }
826
828
829 if (left > 0) {
830
831 m << (Int_t)kRRT_LogFile << left;
832 fSocket->Send(m);
833
834 const Int_t kMAXBUF = 32768; //16384 //65536;
835 char buf[kMAXBUF];
836 Int_t wanted = (left > kMAXBUF) ? kMAXBUF : left;
837 Int_t len;
838 do {
839 while ((len = read(fLogFileDes, buf, wanted)) < 0 &&
842
843 if (len < 0) {
844 SysError("SendLogFile", "error reading log file");
845 break;
846 }
847
848 if (end == ltot && len == wanted)
849 buf[len-1] = '\n';
850
851 if (fSocket->SendRaw(buf, len) < 0) {
852 SysError("SendLogFile", "error sending log file");
853 break;
854 }
855
856 // Update counters
857 left -= len;
858 wanted = (left > kMAXBUF) ? kMAXBUF : left;
859
860 } while (len > 0 && left > 0);
861 }
862
863 // Restore initial position if partial send
864 if (adhoc)
866
867 m.Reset();
868 m << (Int_t)kRRT_LogDone << status;
869
870 fSocket->Send(m);
871}
872
873////////////////////////////////////////////////////////////////////////////////
874/// Send any created canvas to client
875
877{
878 Int_t nc = 0;
879
880 // Send back new canvases
882 TIter next(gROOT->GetListOfCanvases());
883 TObject *o = 0;
884 while ((o = next())) {
885 if (!fSentCanvases)
886 fSentCanvases = new TList;
888 // We cannot use FindObject here because there may be invalid
889 // objects in the send list (i.e. deleted canvases)
891 while (lnk) {
892 TObject *sc = lnk->GetObject();
893 lnk = lnk->Next();
894 if ((!ROOT::Detail::HasBeenDeleted(sc)) && sc == o)
896 }
897 if (!sentalready) {
898 if (gDebug > 0)
899 Info("SendCanvases","new canvas found: %p", o);
900 mess.Reset(kMESS_OBJECT);
901 mess.WriteObject(o);
902 fSocket->Send(mess);
903 nc++;
904 fSentCanvases->Add(o);
905 }
906 }
907 return nc;
908}
909
910////////////////////////////////////////////////////////////////////////////////
911/// Browse directory and send back its content to client.
912
914{
915 Int_t nc = 0;
916
918 if (!fWorkingDir || !dirname || !*dirname) {
919 if (!fWorkingDir)
920 fWorkingDir = new TRemoteObject(fWorkDir, fWorkDir, "TSystemDirectory");
921 TList *list = fWorkingDir->Browse();
922 mess.Reset(kMESS_OBJECT);
923 mess.WriteObject(fWorkingDir);
924 fSocket->Send(mess);
925 nc++;
926 list->Delete();
927 delete list;
928 }
929 else if (fWorkingDir) {
930 TRemoteObject dir(dirname, dirname, "TSystemDirectory");
931 TList *list = dir.Browse();
932 mess.Reset(kMESS_OBJECT);
933 mess.WriteObject(list);
934 fSocket->Send(mess);
935 nc++;
936 list->Delete();
937 delete list;
938 }
939 return nc;
940}
941
942////////////////////////////////////////////////////////////////////////////////
943/// Browse root file and send back its content;
944/// if fname is null, send the full list of files.
945
947{
948 Int_t nc = 0;
949
950 TList *list = new TList;
952 if (!fname || !*fname) {
953 // fname is null, so send the list of files.
954 TIter next(gROOT->GetListOfFiles());
955 TNamed *fh = 0;
957 while ((fh = (TNamed *)next())) {
958 robj = new TRemoteObject(fh->GetName(), fh->GetTitle(), "TFile");
959 list->Add(robj);
960 }
961 if (list->GetEntries() > 0) {
962 mess.Reset(kMESS_OBJECT);
963 mess.WriteObject(list);
964 fSocket->Send(mess);
965 nc++;
966 }
967 }
968 else {
969 // get Root file content and send the list of objects
970 TDirectory *fh = (TDirectory *)gROOT->GetListOfFiles()->FindObject(fname);
971 if (fh) {
972 fh->cd();
973 TRemoteObject dir(fh->GetName(), fh->GetTitle(), "TFile");
974 TList *keylist = (TList *)gROOT->ProcessLine(Form("((TFile *)0x%zx)->GetListOfKeys();", (size_t)fh));
976 TNamed *key = 0;
978 while ((key = (TNamed *)nextk())) {
979 robj = new TRemoteObject(key->GetName(), key->GetTitle(), "TKey");
980 const char *classname = (const char *)gROOT->ProcessLine(Form("((TKey *)0x%zx)->GetClassName();", (size_t)key));
981 robj->SetKeyClassName(classname);
982 Bool_t isFolder = (Bool_t)gROOT->ProcessLine(Form("((TKey *)0x%zx)->IsFolder();", (size_t)key));
983 robj->SetFolder(isFolder);
984 robj->SetRemoteAddress((Longptr_t) key);
985 list->Add(robj);
986 }
987 if (list->GetEntries() > 0) {
988 mess.Reset(kMESS_OBJECT);
989 mess.WriteObject(list);
990 fSocket->Send(mess);
991 nc++;
992 }
993 }
994 }
995
996 list->Delete();
997 delete list;
998
999 return nc;
1000}
1001
1002////////////////////////////////////////////////////////////////////////////////
1003/// Read key object and send it back to client.
1004
1006{
1007 Int_t nc = 0;
1008
1010 TNamed *obj = (TNamed *)gROOT->ProcessLine(Form("gFile->GetKey(\"%s\")->ReadObj();", keyname));
1011 if (obj) {
1012 mess.Reset(kMESS_OBJECT);
1013 mess.WriteObject(obj);
1014 fSocket->Send(mess);
1015 nc++;
1016 }
1017 return nc;
1018}
1019
1020////////////////////////////////////////////////////////////////////////////////
1021/// Terminate the server.
1022
1024{
1025 // Close and remove the log file; remove the cleanup script
1026 if (fLogFile) {
1028 // Delete the log file unless we are in debug mode
1029 if (gDebug <= 0)
1031 TString cleanup = fLogFilePath;
1032 cleanup.ReplaceAll(".log", ".cleanup");
1033 gSystem->Unlink(cleanup);
1034 }
1035
1036 // Remove input handler to avoid spurious signals in socket
1037 // selection for closing activities executed upon exit()
1039 TObject *fh = 0;
1040 while ((fh = next())) {
1041 TASInputHandler *ih = dynamic_cast<TASInputHandler *>(fh);
1042 if (ih)
1044 }
1045
1046 // Stop processing events
1047 gSystem->Exit(status);
1048}
1049
1050////////////////////////////////////////////////////////////////////////////////
1051/// Handle file checking request.
1052
1054{
1056 TMD5 md5;
1058
1059 // Parse message
1060 (*mess) >> filenam >> md5;
1061
1062 // check file in working directory
1064 if (md5local && md5 == (*md5local)) {
1065 // We have an updated copy of the file
1066 m << (Int_t) kRRT_CheckFile << (Bool_t) kTRUE;
1067 fSocket->Send(m);
1068 if (gDebug > 0)
1069 Info("HandleCheckFile", "up-to-date version of %s available", filenam.Data());
1070 } else {
1072 fSocket->Send(m);
1073 if (gDebug > 0)
1074 Info("HandleCheckFile", "file %s needs to be uploaded", filenam.Data());
1075 }
1076 delete md5local;
1077}
1078
1079////////////////////////////////////////////////////////////////////////////////
1080/// The error handler function. It prints the message on stderr and
1081/// if abort is set it aborts the application.
1082
1083void TApplicationServer::ErrorHandler(Int_t level, Bool_t abort, const char *location,
1084 const char *msg)
1085{
1086 if (gErrorIgnoreLevel == kUnset) {
1088 if (gEnv) {
1089 TString slevel = gEnv->GetValue("Root.ErrorIgnoreLevel", "Print");
1090 if (!slevel.CompareTo("Print", TString::kIgnoreCase))
1092 else if (!slevel.CompareTo("Info", TString::kIgnoreCase))
1094 else if (!slevel.CompareTo("Warning", TString::kIgnoreCase))
1096 else if (!slevel.CompareTo("Error", TString::kIgnoreCase))
1098 else if (!slevel.CompareTo("Break", TString::kIgnoreCase))
1100 else if (!slevel.CompareTo("SysError", TString::kIgnoreCase))
1102 else if (!slevel.CompareTo("Fatal", TString::kIgnoreCase))
1104 }
1105 }
1106
1107 if (level < gErrorIgnoreLevel)
1108 return;
1109
1110 static TString syslogService;
1111
1112 if (syslogService.IsNull()) {
1113 syslogService = "server";
1115 }
1116
1117 const char *type = 0;
1119
1120 if (level >= kPrint) {
1122 type = "Print";
1123 }
1124 if (level >= kInfo) {
1126 type = "Info";
1127 }
1128 if (level >= kWarning) {
1130 type = "Warning";
1131 }
1132 if (level >= kError) {
1133 loglevel = kLogErr;
1134 type = "Error";
1135 }
1136 if (level >= kBreak) {
1137 loglevel = kLogErr;
1138 type = "*** Break ***";
1139 }
1140 if (level >= kSysError) {
1141 loglevel = kLogErr;
1142 type = "SysError";
1143 }
1144 if (level >= kFatal) {
1145 loglevel = kLogErr;
1146 type = "Fatal";
1147 }
1148
1149 TString node = "server";
1150 TString buf;
1151
1152 if (!location || !location[0] ||
1153 (level >= kPrint && level < kInfo) ||
1154 (level >= kBreak && level < kSysError)) {
1155 fprintf(stderr, "%s on %s: %s\n", type, node.Data(), msg);
1156 buf.Form("%s:%s:%s", node.Data(), type, msg);
1157 } else {
1158 fprintf(stderr, "%s in <%s> on %s: %s\n", type, location, node.Data(), msg);
1159 buf.Form("%s:%s:<%s>:%s", node.Data(), type, location, msg);
1160 }
1161 fflush(stderr);
1162
1164
1165 if (abort) {
1166 fprintf(stderr, "aborting\n");
1167 fflush(stderr);
1169 gSystem->Abort();
1170 }
1171}
1172
1173////////////////////////////////////////////////////////////////////////////////
1174/// Parse a command line received from the client, making sure that the files
1175/// needed for the execution, if any, are available. The line is either a C++
1176/// statement or an interpreter command starting with a ".".
1177/// Return the return value of the command casted to a long.
1178
1180{
1181 if (!line || !*line) return 0;
1182
1183 // If load or execute request we must make sure that we have the files.
1184 // If not we ask the client to send them, blocking until we have everything.
1185 if (!strncmp(line, ".L", 2) || !strncmp(line, ".U", 2) ||
1186 !strncmp(line, ".X", 2) || !strncmp(line, ".x", 2)) {
1188 TString arguments;
1189 TString io;
1190 TString fname = gSystem->SplitAclicMode(line+3, aclicMode, arguments, io);
1191
1193 if (!imp) {
1194
1195 // Make sure that we can write in the directory where we are
1197 Error("ProcessLine","no write permission in %s", gSystem->WorkingDirectory());
1198 return 0;
1199 }
1200
1201 if (gDebug > 0)
1202 Info("ProcessLine", "macro %s not found in path %s: asking the client",
1203 fname.Data(), TROOT::GetMacroPath());
1206 fSocket->Send(m);
1207
1208 // Wait for the reply(ies)
1209 Int_t type;
1211
1212 while (filefollows) {
1213
1214 // Get a message
1215 TMessage *rm = 0;
1216 if (fSocket->Recv(rm) <= 0) {
1217 Error("ProcessLine","ask-file: received empty message from client");
1218 return 0;
1219 }
1220 if (rm->What() != kMESS_ANY) {
1221 Error("ProcessLine","ask-file: wrong message received (what: %d)", rm->What());
1222 return 0;
1223 }
1224 (*rm) >> type;
1225 if (type != kRRT_SendFile) {
1226 Error("ProcessLine","ask-file: wrong sub-type received (type: %d)", type);
1227 return 0;
1228 }
1229 (*rm) >> filefollows;
1230 if (filefollows) {
1231 // Read the file specifications
1232 if (fSocket->Recv(rm) <= 0) {
1233 Error("ProcessLine","file: received empty message from client");
1234 return 0;
1235 }
1236 if (rm->What() != kMESS_ANY) {
1237 Error("ProcessLine","file: wrong message received (what: %d)", rm->What());
1238 return 0;
1239 }
1240 (*rm) >> type;
1241 if (type != kRRT_File) {
1242 Error("ProcessLine","file: wrong sub-type received (type: %d)", type);
1243 return 0;
1244 }
1245 // A file follows
1246 char str[2048];
1247 rm->ReadString(str, sizeof(str));
1248 char name[2048], i1[20], i2[40];
1249 sscanf(str, "%2047s %19s %39s", name, i1, i2);
1250 Int_t bin = atoi(i1);
1251 Long_t size = atol(i2);
1253 }
1254 }
1255 }
1256 delete [] imp;
1257 }
1258
1259 // Process the line now
1261}
1262
1263////////////////////////////////////////////////////////////////////////////////
1264/// Execute logon macro's. There are three levels of logon macros that
1265/// will be executed: the system logon etc/system.rootlogon.C, the global
1266/// user logon ~/.rootlogon.C and the local ./.rootlogon.C. For backward
1267/// compatibility also the logon macro as specified by the Rint.Logon
1268/// environment setting, by default ./rootlogon.C, will be executed.
1269/// No logon macros will be executed when the system is started with
1270/// the -n option.
1271
1273{
1274 if (NoLogOpt()) return;
1275
1276 TString name = ".rootlogon.C";
1277 TString sname = "system";
1278 sname += name;
1283 ProcessFile(s);
1284 }
1287 ProcessFile(s);
1288 }
1289 // avoid executing ~/.rootlogon.C twice
1293 }
1294
1295 // execute also the logon macro specified by "Rint.Logon"
1296 const char *logon = gEnv->GetValue("Rint.Logon", (char*)0);
1297 if (logon) {
1299 if (mac)
1301 delete [] mac;
1302 }
1303}
@ kMESS_STRING
@ kMESS_ANY
@ kMESS_OBJECT
@ kROOTD_PROTOCOL
@ kMESS_CINT
#define SafeDelete(p)
Definition RConfig.hxx:507
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
bool Bool_t
Boolean (0=false, 1=true) (bool)
Definition RtypesCore.h:78
int Int_t
Signed integer 4 bytes (int)
Definition RtypesCore.h:60
long Longptr_t
Integer large enough to hold a pointer (platform-dependent)
Definition RtypesCore.h:90
long Long_t
Signed long integer 4 bytes (long). Size depends on architecture.
Definition RtypesCore.h:69
constexpr Bool_t kFALSE
Definition RtypesCore.h:109
long long Long64_t
Portable signed long integer 8 bytes.
Definition RtypesCore.h:84
constexpr Bool_t kTRUE
Definition RtypesCore.h:108
R__EXTERN TBenchmark * gBenchmark
Definition TBenchmark.h:59
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
#define gDirectory
Definition TDirectory.h:385
R__EXTERN TEnv * gEnv
Definition TEnv.h:126
Int_t gErrorAbortLevel
non-ignored errors with level equal or above this value will call abort(). Default is kSysError+1.
Definition TError.cxx:34
constexpr Int_t kError
Definition TError.h:47
constexpr Int_t kFatal
Definition TError.h:50
constexpr Int_t kWarning
Definition TError.h:46
void Error(const char *location, const char *msgfmt,...)
Use this function in case an error occurred.
Definition TError.cxx:208
constexpr Int_t kBreak
Definition TError.h:48
constexpr Int_t kPrint
Definition TError.h:44
constexpr Int_t kInfo
Definition TError.h:45
Int_t gErrorIgnoreLevel
errors with level below this value will be ignored. Default is kUnset.
Definition TError.cxx:33
constexpr Int_t kSysError
Definition TError.h:49
ErrorHandlerFunc_t SetErrorHandler(ErrorHandlerFunc_t newhandler)
Set an errorhandler function. Returns the old handler.
Definition TError.cxx:92
constexpr Int_t kUnset
Definition TError.h:43
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.
winID h TVirtualViewer3D TVirtualGLPainter p
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t r
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void on
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t UChar_t len
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t type
char name[80]
Definition TGX11.cxx:142
#define gInterpreter
Int_t gDebug
Global variable setting the debug level. Set to 0 to disable, increase it in steps of 1 to increase t...
Definition TROOT.cxx:792
#define gROOT
Definition TROOT.h:417
char * Form(const char *fmt,...)
Formats a string in a circular formatting buffer.
Definition TString.cxx:2571
@ kSigPipe
@ kSigUrgent
@ kKeepAlive
Definition TSystem.h:233
@ kBytesToRead
Definition TSystem.h:239
@ kNoDelay
Definition TSystem.h:235
@ kProcessGroup
Definition TSystem.h:237
@ kAtMark
Definition TSystem.h:238
@ kOob
Definition TSystem.h:244
@ kReadPermission
Definition TSystem.h:55
@ kWritePermission
Definition TSystem.h:54
@ kLogLocal5
Definition TSystem.h:80
ELogLevel
Definition TSystem.h:63
@ kLogWarning
Definition TSystem.h:68
@ kLogInfo
Definition TSystem.h:70
@ kLogErr
Definition TSystem.h:67
R__EXTERN TSystem * gSystem
Definition TSystem.h:582
@ kLogPid
Definition TSystem.h:59
@ kLogCons
Definition TSystem.h:60
Bool_t Notify() override
Handle this input.
TASInputHandler(TApplicationServer *s, Int_t fd)
TApplicationServer * fServ
Bool_t ReadNotify() override
Notify when something can be read from the descriptor associated with this handler.
TApplicationServer * fServ
Bool_t Notify() override
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.
Bool_t Notify() override
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.
static void SetDefaultPrefix(const char *pfx)
Static method to set the default prefix.
Bool_t Notify() override
Handle this signal.
TApplicationServer * fServ
TASSigPipeHandler(TApplicationServer *s)
void Run(Bool_t retrn=kFALSE) override
Main server eventloop.
void ExecLogon()
Execute logon macro's.
Int_t SendCanvases()
Send any created canvas to client.
Longptr_t ProcessLine(const char *line, Bool_t=kFALSE, Int_t *err=nullptr) override
Parse a command line received from the client, making sure that the files needed for the execution,...
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 Reset(const char *dir)
Reset environment to be ready for execution of next command.
void GetOptions(Int_t *argc, char **argv) override
Get and handle command line options.
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.
void Terminate(Int_t status) override
Terminate the server.
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...
virtual Longptr_t ProcessLine(const char *line, Bool_t sync=kFALSE, Int_t *error=nullptr)
Process a single command line, either a C++ statement or an interpreter command starting with a "....
virtual void Run(Bool_t retrn=kFALSE)
Main application eventloop. Calls system dependent eventloop via gSystem.
virtual Longptr_t ProcessFile(const char *file, Int_t *error=nullptr, Bool_t keep=kFALSE)
Process a file containing a C++ macro.
Bool_t NoLogOpt() const
This class is a ROOT utility to help benchmarking applications.
Definition TBenchmark.h:29
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 Int_t GetValue(const char *name, Int_t dflt) const
Returns the integer value for a resource.
Definition TEnv.cxx:511
void SetFd(int fd)
A doubly linked list.
Definition TList.h:38
void Add(TObject *obj) override
Definition TList.h:81
virtual TObjLink * FirstLink() const
Definition TList.h:107
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:473
The TNamed class is the base class for all named ROOT classes.
Definition TNamed.h:29
const char * GetName() const override
Returns name of object.
Definition TNamed.h:49
const char * GetTitle() const override
Returns title of object.
Definition TNamed.h:50
Mother of all ROOT objects.
Definition TObject.h:42
R__ALWAYS_INLINE Bool_t TestBit(UInt_t f) const
Definition TObject.h:204
virtual void SysError(const char *method, const char *msgfmt,...) const
Issue system error message.
Definition TObject.cxx:1110
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition TObject.cxx:1082
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
Definition TObject.cxx:886
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition TObject.cxx:1096
virtual void Fatal(const char *method, const char *msgfmt,...) const
Issue fatal error message.
Definition TObject.cxx:1124
void ResetBit(UInt_t f)
Definition TObject.h:203
virtual void Info(const char *method, const char *msgfmt,...) const
Issue info message.
Definition TObject.cxx:1070
static const char * GetMacroPath()
Get macro search path. Static utility function.
Definition TROOT.cxx:2932
static Bool_t Initialized()
Return kTRUE if the TROOT object has been initialized.
Definition TROOT.cxx:3082
static const TString & GetEtcDir()
Get the sysconfig directory in the installation. Static utility function.
Definition TROOT.cxx:3396
The TRemoteObject class provides protocol for browsing ROOT objects from a remote ROOT session.
void Browse(TBrowser *b) override
Browse remote object.
ESignals GetSignal() const
This class implements client sockets.
Definition TSocket.h:39
virtual Int_t SetOption(ESockOptions opt, Int_t val)
Set socket options.
Definition TSocket.cxx:1018
virtual Int_t Recv(TMessage *&mess)
Receive a TMessage object.
Definition TSocket.cxx:808
virtual Int_t RecvRaw(void *buffer, Int_t length, ESendRecvOptions opt=kDefault)
Receive a raw buffer of specified length bytes.
Definition TSocket.cxx:903
virtual Int_t SendRaw(const void *buffer, Int_t length, ESendRecvOptions opt=kDefault)
Send a raw buffer of specified length.
Definition TSocket.cxx:610
Option_t * GetOption() const override
Definition TSocket.h:99
virtual Int_t GetDescriptor() const
Definition TSocket.h:113
virtual Int_t Send(const TMessage &mess)
Send a TMessage object.
Definition TSocket.cxx:512
Basic string class.
Definition TString.h:137
Ssiz_t Length() const
Definition TString.h:426
Int_t Atoi() const
Return integer value of string.
Definition TString.cxx:2069
const char * Data() const
Definition TString.h:385
TString & ReplaceAll(const TString &s1, const TString &s2)
Definition TString.h:714
@ kIgnoreCase
Definition TString.h:284
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:1702
static void ResetErrno()
Static function resetting system error number.
Definition TSystem.cxx:287
virtual Bool_t ExpandPathName(TString &path)
Expand a pathname getting rid of special shell characters like ~.
Definition TSystem.cxx:1290
virtual void Openlog(const char *name, Int_t options, ELogFacility facility)
Open connection to system log daemon.
Definition TSystem.cxx:1693
static Int_t GetErrno()
Static function returning system error number.
Definition TSystem.cxx:279
virtual int GetPid()
Get process id.
Definition TSystem.cxx:721
virtual TString SplitAclicMode(const char *filename, TString &mode, TString &args, TString &io) const
This method split a filename of the form:
Definition TSystem.cxx:4344
virtual int mkdir(const char *name, Bool_t recursive=kFALSE)
Make a file system directory.
Definition TSystem.cxx:921
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:402
virtual FILE * OpenPipe(const char *command, const char *mode)
Open a pipe.
Definition TSystem.cxx:665
virtual const char * PrependPathName(const char *dir, TString &name)
Concatenate a directory and a file name.
Definition TSystem.cxx:1097
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:1312
virtual Bool_t ChangeDirectory(const char *path)
Change directory.
Definition TSystem.cxx:877
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:949
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:730
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:886
virtual char * Which(const char *search, const char *file, EAccessMode mode=kFileExists)
Find location of file in a search path.
Definition TSystem.cxx:1564
virtual const char * HomeDirectory(const char *userName=nullptr)
Return the user's home directory.
Definition TSystem.cxx:902
virtual void Abort(int code=0)
Abort the application.
Definition TSystem.cxx:739
virtual int Unlink(const char *name)
Unlink, i.e.
Definition TSystem.cxx:1397
virtual void StackTrace()
Print a stack trace.
Definition TSystem.cxx:748
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:107
TLine * line
const Int_t n
Definition legend1.C:16
R__ALWAYS_INLINE bool HasBeenDeleted(const TObject *obj)
Check if the TObject's memory has been deleted.
Definition TObject.h:409
static const char * what
Definition stlLoader.cc:5
TMarker m
Definition textangle.C:8