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