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