Logo ROOT   6.10/09
Reference Guide
TSystem.cxx
Go to the documentation of this file.
1 // @(#)root/base:$Id: 8944840ba34631ec28efc779647618db43c0eee5 $
2 // Author: Fons Rademakers 15/09/95
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2000, 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 /** \class TSystem
13 \ingroup Base
14 
15 Abstract base class defining a generic interface to the underlying
16 Operating System.
17 This is not an ABC in the strict sense of the (C++) word. For
18 every member function there is an implementation (often not more
19 than a call to AbstractMethod() which prints a warning saying
20 that the method should be overridden in a derived class), which
21 allows a simple partial implementation for new OS'es.
22 */
23 
24 #ifdef WIN32
25 #include <io.h>
26 #endif
27 #include <stdlib.h>
28 #include <errno.h>
29 #include <algorithm>
30 #include <sys/stat.h>
31 
32 #include "Riostream.h"
33 #include "TSystem.h"
34 #include "TApplication.h"
35 #include "TException.h"
36 #include "TROOT.h"
37 #include "TClass.h"
38 #include "TClassTable.h"
39 #include "TEnv.h"
40 #include "TBrowser.h"
41 #include "TString.h"
42 #include "TOrdCollection.h"
43 #include "TObject.h"
44 #include "TInterpreter.h"
45 #include "TRegexp.h"
46 #include "TTimer.h"
47 #include "TObjString.h"
48 #include "TError.h"
49 #include "TPluginManager.h"
50 #include "TUrl.h"
51 #include "TVirtualMutex.h"
52 #include "TVersionCheck.h"
53 #include "compiledata.h"
54 #include "RConfigure.h"
55 
56 const char *gRootDir;
57 const char *gProgName;
58 const char *gProgPath;
59 
61 TFileHandler *gXDisplay = 0; // Display server event handler, set in TGClient
62 
63 static Int_t *gLibraryVersion = 0; // Set in TVersionCheck, used in Load()
64 static Int_t gLibraryVersionIdx = 0; // Set in TVersionCheck, used in Load()
66 
67 
69 
70 ////////////////////////////////////////////////////////////////////////////////
71 /// Create async event processor timer. Delay is in milliseconds.
72 
74 {
75  gROOT->SetInterrupt(kFALSE);
76  TurnOn();
77 }
78 
79 ////////////////////////////////////////////////////////////////////////////////
80 /// Process events if timer did time out. Returns kTRUE if interrupt
81 /// flag is set (by hitting a key in the canvas or selecting the
82 /// Interrupt menu item in canvas or some other action).
83 
85 {
86  if (fTimeout) {
87  if (gSystem->ProcessEvents()) {
88  Remove();
89  return kTRUE;
90  } else {
91  Reset();
92  return kFALSE;
93  }
94  }
95  return kFALSE;
96 }
97 
98 
99 
101 
103 
104 ////////////////////////////////////////////////////////////////////////////////
105 /// Create a new OS interface.
106 
107 TSystem::TSystem(const char *name, const char *title) : TNamed(name, title), fAclicProperties(0)
108 {
109  if (gSystem && name[0] != '-' && strcmp(name, "Generic"))
110  Error("TSystem", "only one instance of TSystem allowed");
111 
112  fOnExitList = 0;
113  fSignalHandler = 0;
114  fFileHandler = 0;
115  fStdExceptionHandler = 0;
116  fTimers = 0;
117  fCompiled = 0;
118  fHelpers = 0;
119  fInsideNotify = kFALSE;
120  fBeepDuration = 0;
121  fBeepFreq = 0;
122  fReadmask = 0;
123  fWritemask = 0;
124  fReadready = 0;
125  fWriteready = 0;
126  fSignals = 0;
127  fDone = kFALSE;
128  fAclicMode = kDefault;
129  fInControl = kFALSE;
130  fLevel = 0;
131  fMaxrfd = -1;
132  fMaxwfd = -1;
133  fNfd = 0;
134  fSigcnt = 0;
135 
136  if (!gLibraryVersion) {
138  memset(gLibraryVersion, 0, gLibraryVersionMax*sizeof(Int_t));
139  }
140 }
141 
142 ////////////////////////////////////////////////////////////////////////////////
143 /// Delete the OS interface.
144 
146 {
147  if (fOnExitList) {
148  fOnExitList->Delete();
149  SafeDelete(fOnExitList);
150  }
151 
152  if (fSignalHandler) {
153  fSignalHandler->Delete();
154  SafeDelete(fSignalHandler);
155  }
156 
157  if (fFileHandler) {
158  fFileHandler->Delete();
159  SafeDelete(fFileHandler);
160  }
161 
162  if (fStdExceptionHandler) {
163  fStdExceptionHandler->Delete();
164  SafeDelete(fStdExceptionHandler);
165  }
166 
167  if (fTimers) {
168  fTimers->Delete();
169  SafeDelete(fTimers);
170  }
171 
172  if (fCompiled) {
173  fCompiled->Delete();
174  SafeDelete(fCompiled);
175  }
176 
177  if (fHelpers) {
178  fHelpers->Delete();
179  SafeDelete(fHelpers);
180  }
181 
182  if (gSystem == this)
183  gSystem = 0;
184 }
185 
186 ////////////////////////////////////////////////////////////////////////////////
187 /// Initialize the OS interface.
188 
190 {
191  fNfd = 0;
192  fMaxrfd = -1;
193  fMaxwfd = -1;
194 
195  fSigcnt = 0;
196  fLevel = 0;
197 
198  fSignalHandler = new TOrdCollection;
199  fFileHandler = new TOrdCollection;
200  fStdExceptionHandler = new TOrdCollection;
201  fTimers = new TOrdCollection;
202 
203  fBuildArch = BUILD_ARCH;
204  fBuildCompiler = COMPILER;
205  fBuildCompilerVersion = COMPILERVERS;
206  fBuildNode = BUILD_NODE;
207  fFlagsDebug = CXXDEBUG;
208  fFlagsOpt = CXXOPT;
209  fIncludePath = INCLUDEPATH;
210  fLinkedLibs = LINKEDLIBS;
211  fSoExt = SOEXT;
212  fObjExt = OBJEXT;
213  fAclicMode = kDefault;
214  fMakeSharedLib = MAKESHAREDLIB;
215  fMakeExe = MAKEEXE;
216  fCompiled = new TOrdCollection;
217 
218  if (gEnv && fBeepDuration == 0 && fBeepFreq == 0) {
219  fBeepDuration = gEnv->GetValue("Root.System.BeepDuration", 100);
220  fBeepFreq = gEnv->GetValue("Root.System.BeepFreq", 440);
221  }
222  if (!fName.CompareTo("Generic")) return kTRUE;
223  return kFALSE;
224 }
225 
226 ////////////////////////////////////////////////////////////////////////////////
227 /// Set the application name (from command line, argv[0]) and copy it in
228 /// gProgName.
229 
230 void TSystem::SetProgname(const char *name)
231 {
232  gProgName = StrDup(name);
233 }
234 
235 ////////////////////////////////////////////////////////////////////////////////
236 /// Set DISPLAY environment variable based on utmp entry. Only for UNIX.
237 
239 {
240 }
241 
242 ////////////////////////////////////////////////////////////////////////////////
243 /// Set the system error string. This string will be used by GetError().
244 /// To be used in case one does not want or can use the system error
245 /// string (e.g. because error is generated by a third party POSIX like
246 /// library that does not use standard errno).
247 
248 void TSystem::SetErrorStr(const char *errstr)
249 {
250  ResetErrno(); // so GetError() uses the fLastErrorString
251  GetLastErrorString() = errstr;
252 }
253 
254 ////////////////////////////////////////////////////////////////////////////////
255 /// Return system error string.
256 
257 const char *TSystem::GetError()
258 {
259  if (GetErrno() == 0 && GetLastErrorString() != "")
260  return GetLastErrorString();
261  return Form("errno: %d", GetErrno());
262 }
263 
264 ////////////////////////////////////////////////////////////////////////////////
265 /// Static function returning system error number.
266 
268 {
269 #ifdef _REENTRANT
270  return errno; // errno can be a macro if _REENTRANT is set
271 #else
272 #ifdef R__SOLARIS_CC50
273  return ::errno;
274 #else
275  return errno;
276 #endif
277 #endif
278 }
279 
280 ////////////////////////////////////////////////////////////////////////////////
281 /// Static function resetting system error number.
282 
284 {
285 #ifdef _REENTRANT
286  errno = 0; // errno can be a macro if _REENTRANT is set
287 #else
288 #ifdef R__SOLARIS_CC50
289  ::errno = 0;
290 #else
291  errno = 0;
292 #endif
293 #endif
294 }
295 
296 ////////////////////////////////////////////////////////////////////////////////
297 /// Objects that should be deleted on exit of the OS interface.
298 
300 {
301  if (fOnExitList == 0)
302  fOnExitList = new TOrdCollection;
303  if (fOnExitList->FindObject(obj) == 0)
304  fOnExitList->Add(obj);
305 }
306 
307 ////////////////////////////////////////////////////////////////////////////////
308 /// Return the system's host name.
309 
310 const char *TSystem::HostName()
311 {
312  return "Local host";
313 }
314 
315 ////////////////////////////////////////////////////////////////////////////////
316 /// Hook to tell TSystem that the TApplication object has been created.
317 
319 {
320  // Currently needed only for WinNT interface.
321 }
322 
323 ////////////////////////////////////////////////////////////////////////////////
324 /// Beep for duration milliseconds with a tone of frequency freq.
325 /// Defaults to printing the `\a` character to stdout.
326 /// If freq or duration is <0 respectively, use default value.
327 /// If setDefault is set, only set the frequency and duration as
328 /// new defaults, but don't beep.
329 /// If default freq or duration is <0, never beep (silence)
330 
331 void TSystem::Beep(Int_t freq /*=-1*/, Int_t duration /*=-1*/,
332  Bool_t setDefault /*=kFALSE*/)
333 {
334  if (setDefault) {
335  fBeepFreq = freq;
336  fBeepDuration = duration;
337  return;
338  }
339  if (fBeepDuration < 0 || fBeepFreq < 0) return; // silence
340  if (freq < 0) freq = fBeepFreq;
341  if (duration < 0) duration = fBeepDuration;
342  DoBeep(freq, duration);
343 }
344 
345 //---- EventLoop ---------------------------------------------------------------
346 
347 ////////////////////////////////////////////////////////////////////////////////
348 /// System event loop.
349 
351 {
352  fInControl = kTRUE;
353  fDone = kFALSE;
354 
355 loop_entry:
356  try {
357  RETRY {
358  while (!fDone) {
360  InnerLoop();
362  }
363  } ENDTRY;
364  }
365  catch (std::exception& exc) {
366  TIter next(fStdExceptionHandler);
367  TStdExceptionHandler* eh = 0;
368  while ((eh = (TStdExceptionHandler*) next())) {
369  switch (eh->Handle(exc))
370  {
372  break;
374  goto loop_entry;
375  break;
377  Warning("Run", "instructed to abort");
378  goto loop_end;
379  break;
380  }
381  }
382  throw;
383  }
384  catch (const char *str) {
385  printf("%s\n", str);
386  }
387  // handle every exception
388  catch (...) {
389  Warning("Run", "handle uncaugth exception, terminating");
390  }
391 
392 loop_end:
393  fInControl = kFALSE;
394 }
395 
396 ////////////////////////////////////////////////////////////////////////////////
397 /// Exit from event loop.
398 
400 {
401  fDone = kTRUE;
402 }
403 
404 ////////////////////////////////////////////////////////////////////////////////
405 /// Inner event loop.
406 
408 {
409  fLevel++;
410  DispatchOneEvent();
411  fLevel--;
412 }
413 
414 ////////////////////////////////////////////////////////////////////////////////
415 /// Process pending events (GUI, timers, sockets). Returns the result of
416 /// TROOT::IsInterrupted(). The interrupt flag (TROOT::SetInterrupt())
417 /// can be set during the handling of the events. This mechanism allows
418 /// macros running in tight calculating loops to be interrupted by some
419 /// GUI event (depending on the interval with which this method is
420 /// called). For example hitting ctrl-c in a canvas will set the
421 /// interrupt flag.
422 
424 {
425  gROOT->SetInterrupt(kFALSE);
426 
427  if (!gROOT->TestBit(TObject::kInvalidObject))
428  DispatchOneEvent(kTRUE);
429 
430  return gROOT->IsInterrupted();
431 }
432 
433 ////////////////////////////////////////////////////////////////////////////////
434 /// Dispatch a single event.
435 
437 {
438  AbstractMethod("DispatchOneEvent");
439 }
440 
441 ////////////////////////////////////////////////////////////////////////////////
442 /// Sleep milliSec milli seconds.
443 
445 {
446  AbstractMethod("Sleep");
447 }
448 
449 ////////////////////////////////////////////////////////////////////////////////
450 /// Select on active file descriptors (called by TMonitor).
451 
453 {
454  AbstractMethod("Select");
455  return -1;
456 }
457 ////////////////////////////////////////////////////////////////////////////////
458 /// Select on active file descriptors (called by TMonitor).
459 
461 {
462  AbstractMethod("Select");
463  return -1;
464 }
465 
466 //---- handling of system events -----------------------------------------------
467 ////////////////////////////////////////////////////////////////////////////////
468 /// Get current time in milliseconds since 0:00 Jan 1 1995.
469 
471 {
472  return TTime(0);
473 }
474 
475 ////////////////////////////////////////////////////////////////////////////////
476 /// Add timer to list of system timers.
477 
479 {
480  if (ti && fTimers && (fTimers->FindObject(ti) == 0))
481  fTimers->Add(ti);
482 }
483 
484 ////////////////////////////////////////////////////////////////////////////////
485 /// Remove timer from list of system timers. Returns removed timer or 0
486 /// if timer was not active.
487 
489 {
490  if (fTimers) {
491  TTimer *tr = (TTimer*) fTimers->Remove(ti);
492  return tr;
493  }
494  return 0;
495 }
496 
497 ////////////////////////////////////////////////////////////////////////////////
498 /// Time when next timer of mode (synchronous=kTRUE or
499 /// asynchronous=kFALSE) will time-out (in ms).
500 
502 {
503  if (!fTimers) return -1;
504 
505  TOrdCollectionIter it((TOrdCollection*)fTimers);
506  TTimer *t, *to = 0;
507  Long64_t tt, tnow = Now();
508  Long_t timeout = -1;
509 
510  while ((t = (TTimer *) it.Next())) {
511  if (t->IsSync() == mode) {
512  tt = (Long64_t)t->GetAbsTime() - tnow;
513  if (tt < 0) tt = 0;
514  if (timeout == -1) {
515  timeout = (Long_t)tt;
516  to = t;
517  }
518  if (tt < timeout) {
519  timeout = (Long_t)tt;
520  to = t;
521  }
522  }
523  }
524 
525  if (to && to->IsAsync() && timeout > 0) {
526  if (to->IsInterruptingSyscalls())
527  SigAlarmInterruptsSyscalls(kTRUE);
528  else
529  SigAlarmInterruptsSyscalls(kFALSE);
530  }
531 
532  return timeout;
533 }
534 
535 ////////////////////////////////////////////////////////////////////////////////
536 /// Add a signal handler to list of system signal handlers. Only adds
537 /// the handler if it is not already in the list of signal handlers.
538 
540 {
541  if (h && fSignalHandler && (fSignalHandler->FindObject(h) == 0))
542  fSignalHandler->Add(h);
543 }
544 
545 ////////////////////////////////////////////////////////////////////////////////
546 /// Remove a signal handler from list of signal handlers. Returns
547 /// the handler or 0 if the handler was not in the list of signal handlers.
548 
550 {
551  if (fSignalHandler)
552  return (TSignalHandler *)fSignalHandler->Remove(h);
553 
554  return 0;
555 }
556 
557 ////////////////////////////////////////////////////////////////////////////////
558 /// Add a file handler to the list of system file handlers. Only adds
559 /// the handler if it is not already in the list of file handlers.
560 
562 {
563  if (h && fFileHandler && (fFileHandler->FindObject(h) == 0))
564  fFileHandler->Add(h);
565 }
566 
567 ////////////////////////////////////////////////////////////////////////////////
568 /// Remove a file handler from the list of file handlers. Returns
569 /// the handler or 0 if the handler was not in the list of file handlers.
570 
572 {
573  if (fFileHandler)
574  return (TFileHandler *)fFileHandler->Remove(h);
575 
576  return 0;
577 }
578 
579 ////////////////////////////////////////////////////////////////////////////////
580 /// If reset is true reset the signal handler for the specified signal
581 /// to the default handler, else restore previous behaviour.
582 
583 void TSystem::ResetSignal(ESignals /*sig*/, Bool_t /*reset*/)
584 {
585  AbstractMethod("ResetSignal");
586 }
587 
588 ////////////////////////////////////////////////////////////////////////////////
589 /// Reset signals handlers to previous behaviour.
590 
592 {
593  AbstractMethod("ResetSignals");
594 }
595 
596 ////////////////////////////////////////////////////////////////////////////////
597 /// If ignore is true ignore the specified signal, else restore previous
598 /// behaviour.
599 
600 void TSystem::IgnoreSignal(ESignals /*sig*/, Bool_t /*ignore*/)
601 {
602  AbstractMethod("IgnoreSignal");
603 }
604 
605 ////////////////////////////////////////////////////////////////////////////////
606 /// If ignore is true ignore the interrupt signal, else restore previous
607 /// behaviour. Typically call ignore interrupt before writing to disk.
608 
610 {
611  IgnoreSignal(kSigInterrupt, ignore);
612 }
613 
614 ////////////////////////////////////////////////////////////////////////////////
615 /// Add an exception handler to list of system exception handlers. Only adds
616 /// the handler if it is not already in the list of exception handlers.
617 
619 {
620  if (eh && fStdExceptionHandler && (fStdExceptionHandler->FindObject(eh) == 0))
621  fStdExceptionHandler->Add(eh);
622 }
623 
624 ////////////////////////////////////////////////////////////////////////////////
625 /// Remove an exception handler from list of exception handlers. Returns
626 /// the handler or 0 if the handler was not in the list of exception handlers.
627 
629 {
630  if (fStdExceptionHandler)
631  return (TStdExceptionHandler *)fStdExceptionHandler->Remove(eh);
632 
633  return 0;
634 }
635 
636 ////////////////////////////////////////////////////////////////////////////////
637 /// Return the bitmap of conditions that trigger a floating point exception.
638 
640 {
641  AbstractMethod("GetFPEMask");
642  return 0;
643 }
644 
645 ////////////////////////////////////////////////////////////////////////////////
646 /// Set which conditions trigger a floating point exception.
647 /// Return the previous set of conditions.
648 
650 {
651  AbstractMethod("SetFPEMask");
652  return 0;
653 }
654 
655 //---- Processes ---------------------------------------------------------------
656 
657 ////////////////////////////////////////////////////////////////////////////////
658 /// Execute a command.
659 
660 int TSystem::Exec(const char*)
661 {
662  AbstractMethod("Exec");
663  return -1;
664 }
665 
666 ////////////////////////////////////////////////////////////////////////////////
667 /// Open a pipe.
668 
669 FILE *TSystem::OpenPipe(const char*, const char*)
670 {
671  AbstractMethod("OpenPipe");
672  return 0;
673 }
674 
675 ////////////////////////////////////////////////////////////////////////////////
676 /// Close the pipe.
677 
679 {
680  AbstractMethod("ClosePipe");
681  return -1;
682 }
683 
684 ////////////////////////////////////////////////////////////////////////////////
685 /// Execute command and return output in TString.
686 
687 TString TSystem::GetFromPipe(const char *command)
688 {
689  TString out;
690 
691  FILE *pipe = OpenPipe(command, "r");
692  if (!pipe) {
693  SysError("GetFromPipe", "cannot run command \"%s\"", command);
694  return out;
695  }
696 
697  TString line;
698  while (line.Gets(pipe)) {
699  if (out != "")
700  out += "\n";
701  out += line;
702  }
703 
704  Int_t r = ClosePipe(pipe);
705  if (r) {
706  Error("GetFromPipe", "command \"%s\" returned %d", command, r);
707  }
708  return out;
709 }
710 
711 ////////////////////////////////////////////////////////////////////////////////
712 /// Get process id.
713 
715 {
716  AbstractMethod("GetPid");
717  return -1;
718 }
719 
720 ////////////////////////////////////////////////////////////////////////////////
721 /// Exit the application.
722 
724 {
725  AbstractMethod("Exit");
726 }
727 
728 ////////////////////////////////////////////////////////////////////////////////
729 /// Abort the application.
730 
731 void TSystem::Abort(int)
732 {
733  AbstractMethod("Abort");
734 }
735 
736 ////////////////////////////////////////////////////////////////////////////////
737 /// Print a stack trace.
738 
740 {
741  AbstractMethod("StackTrace");
742 }
743 
744 
745 //---- Directories -------------------------------------------------------------
746 
747 ////////////////////////////////////////////////////////////////////////////////
748 /// Create helper TSystem to handle file and directory operations that
749 /// might be special for remote file access, like via rfiod or rootd.
750 
751 TSystem *TSystem::FindHelper(const char *path, void *dirptr)
752 {
753  if (!fHelpers)
754  fHelpers = new TOrdCollection;
755 
756  TPluginHandler *h;
757  TSystem *helper = 0;
758  if (path) {
759  if (!GetDirPtr()) {
760  TUrl url(path, kTRUE);
761  if (!strcmp(url.GetProtocol(), "file"))
762  return 0;
763  }
764  }
765 
766  // look for existing helpers
767  TIter next(fHelpers);
768  while ((helper = (TSystem*) next()))
769  if (helper->ConsistentWith(path, dirptr))
770  return helper;
771 
772  if (!path)
773  return 0;
774 
775  // create new helper
776  TRegexp re("^root.*:"); // also roots, rootk, etc
777  TString pname = path;
778  if (pname.BeginsWith("xroot:") || pname.Index(re) != kNPOS) {
779  // (x)rootd daemon ...
780  if ((h = gROOT->GetPluginManager()->FindHandler("TSystem", path))) {
781  if (h->LoadPlugin() == -1)
782  return 0;
783  helper = (TSystem*) h->ExecPlugin(2, path, kFALSE);
784  }
785  } else if ((h = gROOT->GetPluginManager()->FindHandler("TSystem", path))) {
786  if (h->LoadPlugin() == -1)
787  return 0;
788  helper = (TSystem*) h->ExecPlugin(0);
789  }
790 
791  if (helper)
792  fHelpers->Add(helper);
793 
794  return helper;
795 }
796 
797 ////////////////////////////////////////////////////////////////////////////////
798 /// Check consistency of this helper with the one required
799 /// by 'path' or 'dirptr'
800 
801 Bool_t TSystem::ConsistentWith(const char *path, void *dirptr)
802 {
803  Bool_t checkproto = kFALSE;
804  if (path) {
805  if (!GetDirPtr()) {
806  TUrl url(path, kTRUE);
807  if (!strncmp(url.GetProtocol(), GetName(), strlen(GetName())))
808  checkproto = kTRUE;
809  }
810  }
811 
812  Bool_t checkdir = kFALSE;
813  if (GetDirPtr() && GetDirPtr() == dirptr)
814  checkdir = kTRUE;
815 
816  return (checkproto || checkdir);
817 }
818 
819 ////////////////////////////////////////////////////////////////////////////////
820 /// Make a directory. Returns 0 in case of success and
821 /// -1 if the directory could not be created (either already exists or
822 /// illegal path name).
823 
824 int TSystem::MakeDirectory(const char*)
825 {
826  AbstractMethod("MakeDirectory");
827  return 0;
828 }
829 
830 ////////////////////////////////////////////////////////////////////////////////
831 /// Open a directory. Returns 0 if directory does not exist.
832 
833 void *TSystem::OpenDirectory(const char*)
834 {
835  AbstractMethod("OpenDirectory");
836  return 0;
837 }
838 
839 ////////////////////////////////////////////////////////////////////////////////
840 /// Free a directory.
841 
843 {
844  AbstractMethod("FreeDirectory");
845 }
846 
847 ////////////////////////////////////////////////////////////////////////////////
848 /// Get a directory entry. Returns 0 if no more entries.
849 
850 const char *TSystem::GetDirEntry(void*)
851 {
852  AbstractMethod("GetDirEntry");
853  return 0;
854 }
855 
856 ////////////////////////////////////////////////////////////////////////////////
857 /// Change directory.
858 
860 {
861  AbstractMethod("ChangeDirectory");
862  return kFALSE;
863 }
864 
865 ////////////////////////////////////////////////////////////////////////////////
866 /// Return working directory.
867 
869 {
870  return 0;
871 }
872 
873 //////////////////////////////////////////////////////////////////////////////
874 /// Return working directory.
875 
876 std::string TSystem::GetWorkingDirectory() const
877 {
878  return std::string();
879 }
880 
881 ////////////////////////////////////////////////////////////////////////////////
882 /// Return the user's home directory.
883 
884 const char *TSystem::HomeDirectory(const char*)
885 {
886  return 0;
887 }
888 
889 //////////////////////////////////////////////////////////////////////////////
890 /// Return the user's home directory.
891 
892 std::string TSystem::GetHomeDirectory(const char*) const
893 {
894  return std::string();
895 }
896 
897 ////////////////////////////////////////////////////////////////////////////////
898 /// Make a file system directory. Returns 0 in case of success and
899 /// -1 if the directory could not be created (either already exists or
900 /// illegal path name).
901 /// If 'recursive' is true, makes parent directories as needed.
902 
903 int TSystem::mkdir(const char *name, Bool_t recursive)
904 {
905  if (recursive) {
906  TString safeName = name; // local copy in case 'name' is output from
907  // TSystem::DirName as it uses static buffers
908  TString dirname = DirName(safeName);
909  if (!dirname.Length()) {
910  // well we should not have to make the root of the file system!
911  // (and this avoid infinite recursions!)
912  return -1;
913  }
914  if (AccessPathName(dirname, kFileExists)) {
915  int res = mkdir(dirname, kTRUE);
916  if (res) return res;
917  }
918  if (!AccessPathName(safeName, kFileExists)) {
919  return -1;
920  }
921  }
922 
923  return MakeDirectory(name);
924 }
925 
926 //---- Paths & Files -----------------------------------------------------------
927 
928 ////////////////////////////////////////////////////////////////////////////////
929 /// Base name of a file name. Base name of /user/root is root.
930 
931 const char *TSystem::BaseName(const char *name)
932 {
933  if (name) {
934  if (name[0] == '/' && name[1] == '\0')
935  return name;
936  char *cp;
937  if ((cp = (char*)strrchr(name, '/')))
938  return ++cp;
939  return name;
940  }
941  Error("BaseName", "name = 0");
942  return 0;
943 }
944 
945 ////////////////////////////////////////////////////////////////////////////////
946 /// Return true if dir is an absolute pathname.
947 
949 {
950  if (dir)
951  return dir[0] == '/';
952  return kFALSE;
953 }
954 
955 ////////////////////////////////////////////////////////////////////////////////
956 /// Return true if 'name' is a file that can be found in the ROOT include
957 /// path or the current directory.
958 /// If 'name' contains any ACLiC style information (e.g. trailing +[+][g|O]),
959 /// it will be striped off 'name'.
960 /// If fullpath is != 0, the full path to the file is returned in *fullpath,
961 /// which must be deleted by the caller.
962 
963 Bool_t TSystem::IsFileInIncludePath(const char *name, char **fullpath)
964 {
965  if (!name || !name[0]) return kFALSE;
966 
967  TString aclicMode;
968  TString arguments;
969  TString io;
970  TString realname = SplitAclicMode(name, aclicMode, arguments, io);
971 
972  TString fileLocation = DirName(realname);
973 
974  TString incPath = gSystem->GetIncludePath(); // of the form -Idir1 -Idir2 -Idir3
975  incPath.Append(":").Prepend(" ");
976  incPath.ReplaceAll(" -I",":"); // of form :dir1 :dir2:dir3
977  while ( incPath.Index(" :") != -1 ) {
978  incPath.ReplaceAll(" :",":");
979  }
980  // Remove double quotes around path expressions.
981  incPath.ReplaceAll("\":", ":");
982  incPath.ReplaceAll(":\"", ":");
983 
984  incPath.Prepend(fileLocation+":.:");
985 
986  char *actual = Which(incPath,realname);
987 
988  if (!actual) {
989  return kFALSE;
990  } else {
991  if (fullpath)
992  *fullpath = actual;
993  else
994  delete [] actual;
995  return kTRUE;
996  }
997 }
998 
999 ////////////////////////////////////////////////////////////////////////////////
1000 /// Return the directory name in pathname. DirName of /user/root is /user.
1001 /// In case no dirname is specified "." is returned.
1002 
1003 const char *TSystem::DirName(const char *pathname)
1004 {
1005  if (pathname && strchr(pathname, '/')) {
1006  R__LOCKGUARD2(gSystemMutex);
1007 
1008  static int len = 0;
1009  static char *buf = 0;
1010  int pathlen = strlen(pathname);
1011  if (pathlen > len) {
1012  delete [] buf;
1013  len = pathlen;
1014  buf = new char [len+1];
1015  }
1016  strcpy(buf, pathname);
1017 
1018  char *r = buf+pathlen-1;
1019  // First skip the trailing '/'
1020  while ( r>buf && *(r)=='/') { --r; }
1021  // Then find the next non slash
1022  while ( r>buf && *(r)!='/') { --r; }
1023  // Then skip duplicate slashes
1024  // Note the 'r>buf' is a strict comparison to allows '/topdir' to return '/'
1025  while ( r>buf && *(r)=='/') { --r; }
1026  // If all was cut away, we encountered a rel. path like 'subdir/'
1027  // and ended up at '.'.
1028  if (r==buf && *(r)!='/') {
1029  return ".";
1030  }
1031  // And finally terminate the string to drop off the filename
1032  *(r+1) = '\0';
1033 
1034  return buf;
1035  }
1036  return ".";
1037 }
1038 
1039 ////////////////////////////////////////////////////////////////////////////////
1040 /// Convert from a Unix pathname to a local pathname. E.g. from `/user/root` to
1041 /// `\user\root`.
1042 
1043 const char *TSystem::UnixPathName(const char *name)
1044 {
1045  return name;
1046 }
1047 
1048 ////////////////////////////////////////////////////////////////////////////////
1049 /// Concatenate a directory and a file name. User must delete returned string.
1050 
1051 char *TSystem::ConcatFileName(const char *dir, const char *name)
1052 {
1053  TString nameString(name);
1054  PrependPathName(dir, nameString);
1055  return StrDup(nameString.Data());
1056 }
1057 
1058 ////////////////////////////////////////////////////////////////////////////////
1059 /// Concatenate a directory and a file name.
1060 
1061 const char *TSystem::PrependPathName(const char *, TString&)
1062 {
1063  AbstractMethod("PrependPathName");
1064  return 0;
1065 }
1066 
1067 
1068 //---- Paths & Files -----------------------------------------------------------
1069 
1070 ////////////////////////////////////////////////////////////////////////////////
1071 /// Expand a pathname getting rid of special shell characters like ~.$, etc.
1072 /// For Unix/Win32 compatibility use $(XXX) instead of $XXX when using
1073 /// environment variables in a pathname. If compatibility is not an issue
1074 /// you can use on Unix directly $XXX. This is a protected function called
1075 /// from the OS specific system classes, like TUnixSystem and TWinNTSystem.
1076 /// Returns the expanded filename or 0 in case of error.
1077 
1078 const char *TSystem::ExpandFileName(const char *fname)
1079 {
1080  const int kBufSize = kMAXPATHLEN;
1081  TTHREAD_TLS_ARRAY(char, kBufSize, xname);
1082 
1083  Bool_t res = ExpandFileName(fname, xname, kBufSize);
1084  if (res)
1085  return nullptr;
1086  else
1087  return xname;
1088 }
1089 
1090 //////////////////////////////////////////////////////////////////////////////
1091 /// Expand a pathname getting rid of special shell characters like ~.$, etc.
1092 /// This function is analogous to ExpandFileName(const char *), except that
1093 /// it receives a TString reference of the pathname to be expanded.
1094 /// Returns kTRUE in case of error and kFALSE otherwise.
1095 
1097 {
1098  const int kBufSize = kMAXPATHLEN;
1099  char xname[kBufSize];
1100 
1101  Bool_t res = ExpandFileName(fname.Data(), xname, kBufSize);
1102  if (!res)
1103  fname = xname;
1104 
1105  return res;
1106 }
1107 
1108 ////////////////////////////////////////////////////////////////////////////
1109 /// Private method for pathname expansion.
1110 /// Returns kTRUE in case of error and kFALSE otherwise.
1111 
1112 Bool_t TSystem::ExpandFileName(const char *fname, char *xname, const int kBufSize)
1113 {
1114  int n, ier, iter, lx, ncopy;
1115  char *inp, *out, *x, *t, buff[kBufSize*4];
1116  const char *b, *c, *e;
1117  const char *p;
1118 
1119  iter = 0; xname[0] = 0; inp = buff + kBufSize; out = inp + kBufSize;
1120  inp[-1] = ' '; inp[0] = 0; out[-1] = ' ';
1121  c = fname + strspn(fname, " \t\f\r");
1122  //VP if (isalnum(c[0])) { strcpy(inp, WorkingDirectory()); strcat(inp, "/"); } // add $cwd
1123 
1124  strlcat(inp, c, kBufSize);
1125 
1126 again:
1127  iter++; c = inp; ier = 0;
1128  x = out; x[0] = 0;
1129 
1130  p = 0; e = 0;
1131  if (c[0] == '~' && c[1] == '/') { // ~/ case
1132  std::string hd = GetHomeDirectory();
1133  p = hd.c_str();
1134  e = c + 1;
1135  if (p) { // we have smth to copy
1136  strlcpy(x, p, kBufSize);
1137  x += strlen(p);
1138  c = e;
1139  } else {
1140  ++ier;
1141  ++c;
1142  }
1143  } else if (c[0] == '~' && c[1] != '/') { // ~user case
1144  n = strcspn(c+1, "/ ");
1145  buff[0] = 0;
1146  strncat(buff, c+1, n);
1147  std::string hd = GetHomeDirectory(buff);
1148  e = c+1+n;
1149  if (!hd.empty()) { // we have smth to copy
1150  p = hd.c_str();
1151  strlcpy(x, p, kBufSize);
1152  x += strlen(p);
1153  c = e;
1154  } else {
1155  x++[0] = c[0];
1156  //++ier;
1157  ++c;
1158  }
1159  }
1160 
1161  for ( ; c[0]; c++) {
1162 
1163  p = 0; e = 0;
1164 
1165  if (c[0] == '.' && c[1] == '/' && c[-1] == ' ') { // $cwd
1166  std::string wd = GetWorkingDirectory();
1167  strlcpy(buff, wd.c_str(), kBufSize);
1168  p = buff;
1169  e = c + 1;
1170  }
1171  if (p) { // we have smth to copy */
1172  strlcpy(x, p, kBufSize); x += strlen(p); c = e-1; continue;
1173  }
1174 
1175  if (c[0] != '$') { // not $, simple copy
1176  x++[0] = c[0];
1177  } else { // we have a $
1178  b = c+1;
1179  if (c[1] == '(') b++;
1180  if (c[1] == '{') b++;
1181  if (b[0] == '$')
1182  e = b+1;
1183  else
1184  for (e = b; isalnum(e[0]) || e[0] == '_'; e++) ;
1185  buff[0] = 0; strncat(buff, b, e-b);
1186  p = Getenv(buff);
1187  if (!p) { // too bad, try UPPER case
1188  for (t = buff; (t[0] = toupper(t[0])); t++) ;
1189  p = Getenv(buff);
1190  }
1191  if (!p) { // too bad, try Lower case
1192  for (t = buff; (t[0] = tolower(t[0])); t++) ;
1193  p = Getenv(buff);
1194  }
1195  if (!p && !strcmp(buff, "cwd")) { // it is $cwd
1196  std::string wd = GetWorkingDirectory();
1197  strlcpy(buff, wd.c_str(), kBufSize);
1198  p = buff;
1199  }
1200  if (!p && !strcmp(buff, "$")) { // it is $$ (replace by GetPid())
1201  snprintf(buff,kBufSize*4, "%d", GetPid());
1202  p = buff;
1203  }
1204  if (!p) { // too bad, nothing can help
1205 #ifdef WIN32
1206  // if we're on windows, we can have \\SomeMachine\C$ - don't
1207  // complain about that, if '$' is followed by nothing or a
1208  // path delimiter.
1209  if (c[1] && c[1]!='\\' && c[1]!=';' && c[1]!='/')
1210  ier++;
1211 #else
1212  ier++;
1213 #endif
1214  x++[0] = c[0];
1215  } else { // It is OK, copy result
1216  int lp = strlen(p);
1217  if (lp >= kBufSize) {
1218  // make sure lx will be >= kBufSize (see below)
1219  strlcpy(x, p, kBufSize);
1220  x += kBufSize;
1221  break;
1222  }
1223  strcpy(x,p);
1224  x += lp;
1225  c = (b==c+1) ? e-1 : e;
1226  }
1227  }
1228  }
1229 
1230  x[0] = 0; lx = x - out;
1231  if (ier && iter < 3) { strlcpy(inp, out, kBufSize); goto again; }
1232  ncopy = (lx >= kBufSize) ? kBufSize-1 : lx;
1233  xname[0] = 0; strncat(xname, out, ncopy);
1234 
1235  if (ier || ncopy != lx) {
1236  ::Error("TSystem::ExpandFileName", "input: %s, output: %s", fname, xname);
1237  return kTRUE;
1238  }
1239 
1240  return kFALSE;
1241 }
1242 
1243 
1244 ////////////////////////////////////////////////////////////////////////////////
1245 /// Expand a pathname getting rid of special shell characters like ~.$, etc.
1246 /// For Unix/Win32 compatibility use $(XXX) instead of $XXX when using
1247 /// environment variables in a pathname. If compatibility is not an issue
1248 /// you can use on Unix directly $XXX.
1249 
1251 {
1252  return kFALSE;
1253 }
1254 
1255 ////////////////////////////////////////////////////////////////////////////////
1256 /// Expand a pathname getting rid of special shell characters like ~.$, etc.
1257 /// For Unix/Win32 compatibility use $(XXX) instead of $XXX when using
1258 /// environment variables in a pathname. If compatibility is not an issue
1259 /// you can use on Unix directly $XXX. The user must delete returned string.
1260 
1261 char *TSystem::ExpandPathName(const char *)
1262 {
1263  return 0;
1264 }
1265 
1266 ////////////////////////////////////////////////////////////////////////////////
1267 /// Returns FALSE if one can access a file using the specified access mode.
1268 /// The file name must not contain any special shell characters line ~ or $,
1269 /// in those cases first call ExpandPathName().
1270 /// Attention, bizarre convention of return value!!
1271 
1273 {
1274  return kFALSE;
1275 }
1276 
1277 ////////////////////////////////////////////////////////////////////////////////
1278 /// Returns TRUE if the url in 'path' points to the local file system.
1279 /// This is used to avoid going through the NIC card for local operations.
1280 
1281 Bool_t TSystem::IsPathLocal(const char *path)
1282 {
1283  Bool_t localPath = kTRUE;
1284 
1285  TUrl url(path);
1286  if (strlen(url.GetHost()) > 0) {
1287  // Check locality
1288  localPath = kFALSE;
1289  TInetAddress a(gSystem->GetHostByName(url.GetHost()));
1290  TInetAddress b(gSystem->GetHostByName(gSystem->HostName()));
1291  if (!strcmp(a.GetHostName(), b.GetHostName()) ||
1292  !strcmp(a.GetHostAddress(), b.GetHostAddress())) {
1293  // Host OK
1294  localPath = kTRUE;
1295  // Check the user if specified
1296  if (strlen(url.GetUser()) > 0) {
1297  UserGroup_t *u = gSystem->GetUserInfo();
1298  if (u) {
1299  if (strcmp(u->fUser, url.GetUser()))
1300  // Requested a different user
1301  localPath = kFALSE;
1302  delete u;
1303  }
1304  }
1305  }
1306  }
1307  // Done
1308  return localPath;
1309 }
1310 
1311 ////////////////////////////////////////////////////////////////////////////////
1312 /// Copy a file. If overwrite is true and file already exists the
1313 /// file will be overwritten. Returns 0 when successful, -1 in case
1314 /// of file open failure, -2 in case the file already exists and overwrite
1315 /// was false and -3 in case of error during copy.
1316 
1317 int TSystem::CopyFile(const char *, const char *, Bool_t)
1318 {
1319  AbstractMethod("CopyFile");
1320  return -1;
1321 }
1322 
1323 ////////////////////////////////////////////////////////////////////////////////
1324 /// Rename a file.
1325 
1326 int TSystem::Rename(const char *, const char *)
1327 {
1328  AbstractMethod("Rename");
1329  return -1;
1330 }
1331 
1332 ////////////////////////////////////////////////////////////////////////////////
1333 /// Create a link from file1 to file2.
1334 
1335 int TSystem::Link(const char *, const char *)
1336 {
1337  AbstractMethod("Link");
1338  return -1;
1339 }
1340 
1341 ////////////////////////////////////////////////////////////////////////////////
1342 /// Create a symbolic link from file1 to file2.
1343 
1344 int TSystem::Symlink(const char *, const char *)
1345 {
1346  AbstractMethod("Symlink");
1347  return -1;
1348 }
1349 
1350 ////////////////////////////////////////////////////////////////////////////////
1351 /// Unlink, i.e. remove, a file.
1352 
1353 int TSystem::Unlink(const char *)
1354 {
1355  AbstractMethod("Unlink");
1356  return -1;
1357 }
1358 
1359 ////////////////////////////////////////////////////////////////////////////////
1360 /// Get info about a file: id, size, flags, modification time.
1361 /// - Id is (statbuf.st_dev << 24) + statbuf.st_ino
1362 /// - Size is the file size
1363 /// - Flags is file type: 0 is regular file, bit 0 set executable,
1364 /// bit 1 set directory, bit 2 set special file
1365 /// (socket, fifo, pipe, etc.)
1366 /// Modtime is modification time.
1367 /// The function returns 0 in case of success and 1 if the file could
1368 /// not be stat'ed.
1369 
1370 int TSystem::GetPathInfo(const char *path, Long_t *id, Long_t *size,
1371  Long_t *flags, Long_t *modtime)
1372 {
1373  Long64_t lsize;
1374 
1375  int res = GetPathInfo(path, id, &lsize, flags, modtime);
1376 
1377  if (res == 0 && size) {
1378  if (sizeof(Long_t) == 4 && lsize > kMaxInt) {
1379  Error("GetPathInfo", "file %s > 2 GB, use GetPathInfo() with Long64_t size", path);
1380  *size = kMaxInt;
1381  } else {
1382  *size = (Long_t)lsize;
1383  }
1384  }
1385 
1386  return res;
1387 }
1388 
1389 ////////////////////////////////////////////////////////////////////////////////
1390 /// Get info about a file: id, size, flags, modification time.
1391 /// - Id is (statbuf.st_dev << 24) + statbuf.st_ino
1392 /// - Size is the file size
1393 /// - Flags is file type: 0 is regular file, bit 0 set executable,
1394 /// bit 1 set directory, bit 2 set special file
1395 /// (socket, fifo, pipe, etc.)
1396 /// Modtime is modification time.
1397 /// The function returns 0 in case of success and 1 if the file could
1398 /// not be stat'ed.
1399 
1400 int TSystem::GetPathInfo(const char *path, Long_t *id, Long64_t *size,
1401  Long_t *flags, Long_t *modtime)
1402 {
1403  FileStat_t buf;
1404 
1405  int res = GetPathInfo(path, buf);
1406 
1407  if (res == 0) {
1408  if (id)
1409  *id = (buf.fDev << 24) + buf.fIno;
1410  if (size)
1411  *size = buf.fSize;
1412  if (modtime)
1413  *modtime = buf.fMtime;
1414  if (flags) {
1415  *flags = 0;
1416  if (buf.fMode & (kS_IXUSR|kS_IXGRP|kS_IXOTH))
1417  *flags |= 1;
1418  if (R_ISDIR(buf.fMode))
1419  *flags |= 2;
1420  if (!R_ISREG(buf.fMode) && !R_ISDIR(buf.fMode))
1421  *flags |= 4;
1422  }
1423  }
1424 
1425  return res;
1426 }
1427 
1428 ////////////////////////////////////////////////////////////////////////////////
1429 /// Get info about a file. Info is returned in the form of a FileStat_t
1430 /// structure (see TSystem.h).
1431 /// The function returns 0 in case of success and 1 if the file could
1432 /// not be stat'ed.
1433 
1434 int TSystem::GetPathInfo(const char *, FileStat_t &)
1435 {
1436  AbstractMethod("GetPathInfo(const char*, FileStat_t&)");
1437  return 1;
1438 }
1439 
1440 ////////////////////////////////////////////////////////////////////////////////
1441 /// Get info about a file system: fs type, block size, number of blocks,
1442 /// number of free blocks.
1443 
1444 int TSystem::GetFsInfo(const char *, Long_t *, Long_t *, Long_t *, Long_t *)
1445 {
1446  AbstractMethod("GetFsInfo");
1447  return 1;
1448 }
1449 
1450 ////////////////////////////////////////////////////////////////////////////////
1451 /// Return a user configured or systemwide directory to create
1452 /// temporary files in.
1453 
1454 const char *TSystem::TempDirectory() const
1455 {
1456  AbstractMethod("TempDirectory");
1457  return 0;
1458 }
1459 
1460 ////////////////////////////////////////////////////////////////////////////////
1461 /// Create a secure temporary file by appending a unique
1462 /// 6 letter string to base. The file will be created in
1463 /// a standard (system) directory or in the directory
1464 /// provided in dir. The full filename is returned in base
1465 /// and a filepointer is returned for safely writing to the file
1466 /// (this avoids certain security problems). Returns 0 in case
1467 /// of error.
1468 
1469 FILE *TSystem::TempFileName(TString &, const char *)
1470 {
1471  AbstractMethod("TempFileName");
1472  return 0;
1473 }
1474 
1475 ////////////////////////////////////////////////////////////////////////////////
1476 /// Set the file permission bits. Returns -1 in case or error, 0 otherwise.
1477 
1478 int TSystem::Chmod(const char *, UInt_t)
1479 {
1480  AbstractMethod("Chmod");
1481  return -1;
1482 }
1483 
1484 ////////////////////////////////////////////////////////////////////////////////
1485 /// Set the process file creation mode mask.
1486 
1488 {
1489  AbstractMethod("Umask");
1490  return -1;
1491 }
1492 
1493 ////////////////////////////////////////////////////////////////////////////////
1494 /// Set the a files modification and access times. If actime = 0 it will be
1495 /// set to the modtime. Returns 0 on success and -1 in case of error.
1496 
1497 int TSystem::Utime(const char *, Long_t, Long_t)
1498 {
1499  AbstractMethod("Utime");
1500  return -1;
1501 }
1502 
1503 ////////////////////////////////////////////////////////////////////////////////
1504 /// Find location of file in a search path. Return value points to TString for
1505 /// compatibility with Which(const char *, const char *, EAccessMode).
1506 /// Returns 0 in case file is not found.
1507 
1508 const char *TSystem::FindFile(const char *, TString&, EAccessMode)
1509 {
1510  AbstractMethod("FindFile");
1511  return 0;
1512 }
1513 
1514 ////////////////////////////////////////////////////////////////////////////////
1515 /// Find location of file in a search path. User must delete returned string.
1516 /// Returns 0 in case file is not found.
1517 
1518 char *TSystem::Which(const char *search, const char *wfil, EAccessMode mode)
1519 {
1520  TString wfilString(wfil);
1521  FindFile(search, wfilString, mode);
1522  if (wfilString.IsNull()) return 0;
1523  return StrDup(wfilString.Data());
1524 }
1525 
1526 //---- Users & Groups ----------------------------------------------------------
1527 
1528 ////////////////////////////////////////////////////////////////////////////////
1529 /// Returns the user's id. If user = 0, returns current user's id.
1530 
1531 Int_t TSystem::GetUid(const char * /*user*/)
1532 {
1533  AbstractMethod("GetUid");
1534  return 0;
1535 }
1536 
1537 ////////////////////////////////////////////////////////////////////////////////
1538 /// Returns the effective user id. The effective id corresponds to the
1539 /// set id bit on the file being executed.
1540 
1542 {
1543  AbstractMethod("GetEffectiveUid");
1544  return 0;
1545 }
1546 
1547 ////////////////////////////////////////////////////////////////////////////////
1548 /// Returns the group's id. If group = 0, returns current user's group.
1549 
1550 Int_t TSystem::GetGid(const char * /*group*/)
1551 {
1552  AbstractMethod("GetGid");
1553  return 0;
1554 }
1555 
1556 ////////////////////////////////////////////////////////////////////////////////
1557 /// Returns the effective group id. The effective group id corresponds
1558 /// to the set id bit on the file being executed.
1559 
1561 {
1562  AbstractMethod("GetEffectiveGid");
1563  return 0;
1564 }
1565 
1566 ////////////////////////////////////////////////////////////////////////////////
1567 /// Returns all user info in the UserGroup_t structure. The returned
1568 /// structure must be deleted by the user. In case of error 0 is returned.
1569 
1571 {
1572  AbstractMethod("GetUserInfo");
1573  return 0;
1574 }
1575 
1576 ////////////////////////////////////////////////////////////////////////////////
1577 /// Returns all user info in the UserGroup_t structure. If user = 0, returns
1578 /// current user's id info. The returned structure must be deleted by the
1579 /// user. In case of error 0 is returned.
1580 
1581 UserGroup_t *TSystem::GetUserInfo(const char * /*user*/)
1582 {
1583  AbstractMethod("GetUserInfo");
1584  return 0;
1585 }
1586 
1587 ////////////////////////////////////////////////////////////////////////////////
1588 /// Returns all group info in the UserGroup_t structure. The only active
1589 /// fields in the UserGroup_t structure for this call are:
1590 /// - fGid and fGroup
1591 /// The returned structure must be deleted by the user. In case of
1592 /// error 0 is returned.
1593 
1595 {
1596  AbstractMethod("GetGroupInfo");
1597  return 0;
1598 }
1599 
1600 ////////////////////////////////////////////////////////////////////////////////
1601 /// Returns all group info in the UserGroup_t structure. The only active
1602 /// fields in the UserGroup_t structure for this call are:
1603 /// - fGid and fGroup
1604 /// If group = 0, returns current user's group. The returned structure
1605 /// must be deleted by the user. In case of error 0 is returned.
1606 
1607 UserGroup_t *TSystem::GetGroupInfo(const char * /*group*/)
1608 {
1609  AbstractMethod("GetGroupInfo");
1610  return 0;
1611 }
1612 
1613 //---- environment manipulation ------------------------------------------------
1614 
1615 ////////////////////////////////////////////////////////////////////////////////
1616 /// Set environment variable.
1617 
1618 void TSystem::Setenv(const char*, const char*)
1619 {
1620  AbstractMethod("Setenv");
1621 }
1622 
1623 ////////////////////////////////////////////////////////////////////////////////
1624 /// Unset environment variable.
1625 
1626 void TSystem::Unsetenv(const char *name)
1627 {
1628  Setenv(name, "");
1629 }
1630 
1631 ////////////////////////////////////////////////////////////////////////////////
1632 /// Get environment variable.
1633 
1634 const char *TSystem::Getenv(const char*)
1635 {
1636  AbstractMethod("Getenv");
1637  return 0;
1638 }
1639 
1640 //---- System Logging ----------------------------------------------------------
1641 
1642 ////////////////////////////////////////////////////////////////////////////////
1643 /// Open connection to system log daemon. For the use of the options and
1644 /// facility see the Unix openlog man page.
1645 
1647 {
1648  AbstractMethod("Openlog");
1649 }
1650 
1651 ////////////////////////////////////////////////////////////////////////////////
1652 /// Send mess to syslog daemon. Level is the logging level and mess the
1653 /// message that will be written on the log.
1654 
1655 void TSystem::Syslog(ELogLevel, const char *)
1656 {
1657  AbstractMethod("Syslog");
1658 }
1659 
1660 ////////////////////////////////////////////////////////////////////////////////
1661 /// Close connection to system log daemon.
1662 
1664 {
1665  AbstractMethod("Closelog");
1666 }
1667 
1668 //---- Standard output redirection ---------------------------------------------
1669 
1670 ////////////////////////////////////////////////////////////////////////////////
1671 /// Redirect standard output (stdout, stderr) to the specified file.
1672 /// If the file argument is 0 the output is set again to stderr, stdout.
1673 /// The second argument specifies whether the output should be added to the
1674 /// file ("a", default) or the file be truncated before ("w").
1675 /// The implementations of this function save internally the current state into
1676 /// a static structure.
1677 ///
1678 /// The call can be made reentrant by specifying the opaque structure pointed
1679 /// by 'h', which is filled with the relevant information. The handle 'h'
1680 /// obtained on the first call must then be used in any subsequent call,
1681 /// included ShowOutput, to display the redirected output.
1682 /// Returns 0 on success, -1 in case of error.
1683 
1684 Int_t TSystem::RedirectOutput(const char *, const char *, RedirectHandle_t *)
1685 {
1686  AbstractMethod("RedirectOutput");
1687  return -1;
1688 }
1689 
1690 ////////////////////////////////////////////////////////////////////////////////
1691 /// Display the content associated with the redirection described by the
1692 /// opaque handle 'h'.
1693 
1695 {
1696  // Check input ...
1697  if (!h) {
1698  Error("ShowOutput", "handle not specified");
1699  return;
1700  }
1701 
1702  // ... and file access
1703  if (gSystem->AccessPathName(h->fFile, kReadPermission)) {
1704  Error("ShowOutput", "file '%s' cannot be read", h->fFile.Data());
1705  return;
1706  }
1707 
1708  // Open the file
1709  FILE *f = 0;
1710  if (!(f = fopen(h->fFile.Data(), "r"))) {
1711  Error("ShowOutput", "file '%s' cannot be open", h->fFile.Data());
1712  return;
1713  }
1714 
1715  // Determine the number of bytes to be read from the file.
1716  off_t ltot = lseek(fileno(f), (off_t) 0, SEEK_END);
1717  Int_t begin = (h->fReadOffSet > 0 && h->fReadOffSet < ltot) ? h->fReadOffSet : 0;
1718  lseek(fileno(f), (off_t) begin, SEEK_SET);
1719  Int_t left = ltot - begin;
1720 
1721  // Now readout from file
1722  const Int_t kMAXBUF = 16384;
1723  char buf[kMAXBUF];
1724  Int_t wanted = (left > kMAXBUF-1) ? kMAXBUF-1 : left;
1725  Int_t len;
1726  do {
1727  while ((len = read(fileno(f), buf, wanted)) < 0 &&
1728  TSystem::GetErrno() == EINTR)
1730 
1731  if (len < 0) {
1732  SysError("ShowOutput", "error reading log file");
1733  break;
1734  }
1735 
1736  // Null-terminate
1737  buf[len] = 0;
1738  fprintf(stderr,"%s", buf);
1739 
1740  // Update counters
1741  left -= len;
1742  wanted = (left > kMAXBUF) ? kMAXBUF : left;
1743 
1744  } while (len > 0 && left > 0);
1745 
1746  // Do not display twice the same thing
1747  h->fReadOffSet = ltot;
1748  fclose(f);
1749 }
1750 
1751 //---- Dynamic Loading ---------------------------------------------------------
1752 
1753 ////////////////////////////////////////////////////////////////////////////////
1754 /// Add a new directory to the dynamic path.
1755 
1756 void TSystem::AddDynamicPath(const char *)
1757 {
1758  AbstractMethod("AddDynamicPath");
1759 }
1760 
1761 ////////////////////////////////////////////////////////////////////////////////
1762 /// Return the dynamic path (used to find shared libraries).
1763 
1765 {
1766  AbstractMethod("GetDynamicPath");
1767  return 0;
1768 }
1769 
1770 ////////////////////////////////////////////////////////////////////////////////
1771 /// Set the dynamic path to a new value.
1772 /// If the value of 'path' is zero, the dynamic path is reset to its
1773 /// default value.
1774 
1775 void TSystem::SetDynamicPath(const char *)
1776 {
1777  AbstractMethod("SetDynamicPath");
1778 }
1779 
1780 
1781 ////////////////////////////////////////////////////////////////////////////////
1782 /// Figure out if left and right points to the same
1783 /// object in the file system.
1784 
1785 static bool R__MatchFilename(const char *left, const char *right)
1786 {
1787  if (left == right) return kTRUE;
1788 
1789  if (left==0 || right==0) return kFALSE;
1790 
1791  if ( (strcmp(right,left)==0) ) {
1792  return kTRUE;
1793  }
1794 
1795 #ifdef G__WIN32
1796 
1797  char leftname[_MAX_PATH];
1798  char rightname[_MAX_PATH];
1799  _fullpath( leftname, left, _MAX_PATH );
1800  _fullpath( rightname, right, _MAX_PATH );
1801  return ((stricmp(leftname, rightname)==0));
1802 #else
1803  struct stat rightBuf;
1804  struct stat leftBuf;
1805  return ( ( 0 == stat( left, & leftBuf ) )
1806  && ( 0 == stat( right, & rightBuf ) )
1807  && ( leftBuf.st_dev == rightBuf.st_dev ) // Files on same device
1808  && ( leftBuf.st_ino == rightBuf.st_ino ) // Files on same inode (but this is not unique on AFS so we need the next 2 test
1809  && ( leftBuf.st_size == rightBuf.st_size ) // Files of same size
1810  && ( leftBuf.st_mtime == rightBuf.st_mtime ) // Files modified at the same time
1811  );
1812 #endif
1813 }
1814 
1815 ////////////////////////////////////////////////////////////////////////////////
1816 /// Load a shared library. Returns 0 on successful loading, 1 in
1817 /// case lib was already loaded, -1 in case lib does not exist
1818 /// or in case of error and -2 in case of version mismatch.
1819 /// When entry is specified the loaded lib is
1820 /// searched for this entry point (return -1 when entry does not exist,
1821 /// 0 otherwise). When the system flag is kTRUE, the library is considered
1822 /// a permanent system library that should not be unloaded during the
1823 /// course of the session.
1824 
1825 int TSystem::Load(const char *module, const char *entry, Bool_t system)
1826 {
1827  // don't load libraries that have already been loaded
1828  TString libs( GetLibraries() );
1829  TString moduleBasename( BaseName(module) );
1830  TString l(moduleBasename);
1831 
1832  Ssiz_t idx = l.Last('.');
1833  if (idx != kNPOS) {
1834  l.Remove(idx+1);
1835  }
1836  for (idx = libs.Index(l); idx != kNPOS; idx = libs.Index(l,idx+1)) {
1837  // The libs contains the sub-string 'l', let's make sure it is
1838  // not just part of a larger name.
1839  if (idx == 0 || libs[idx-1] == '/' || libs[idx-1] == '\\') {
1840  Ssiz_t len = libs.Length();
1841  idx += l.Length();
1842  if (!l.EndsWith(".") && libs[idx]=='.')
1843  idx++;
1844  // Skip the soversion.
1845  while (idx < len && isdigit(libs[idx])) {
1846  ++idx;
1847  // No need to test for len here, at worse idx==len and lib[idx]=='\0'
1848  if (libs[idx] == '.') {
1849  ++idx;
1850  }
1851  }
1852  while (idx < len && libs[idx] != '.') {
1853  if (libs[idx] == ' ' || idx+1 == len) {
1854  return 1;
1855  }
1856  ++idx;
1857  }
1858  }
1859  }
1860  if (l[l.Length()-1] == '.') {
1861  l.Remove(l.Length()-1);
1862  }
1863  if (l.BeginsWith("lib")) {
1864  l.Replace(0, 3, "-l");
1865  for(idx = libs.Index(l); idx != kNPOS; idx = libs.Index(l,idx+1)) {
1866  if ((idx == 0 || libs[idx-1] == ' ') &&
1867  (libs[idx+l.Length()] == ' ' || libs[idx+l.Length()] == 0)) {
1868  return 1;
1869  }
1870  }
1871  }
1872 
1873  char *path = DynamicPathName(module);
1874 
1875  int ret = -1;
1876  if (path) {
1877  // load any dependent libraries
1878  TString deplibs = gInterpreter->GetSharedLibDeps(moduleBasename);
1879  if (deplibs.IsNull()) {
1880  TString libmapfilename;
1881  libmapfilename = path;
1882  idx = libmapfilename.Last('.');
1883  if (idx != kNPOS) {
1884  libmapfilename.Remove(idx);
1885  }
1886  libmapfilename += ".rootmap";
1887  if (gSystem->GetPathInfo(libmapfilename, 0, (Long_t*)0, 0, 0) == 0) {
1888  if (gDebug > 0) Info("Load", "loading %s", libmapfilename.Data());
1889  gInterpreter->LoadLibraryMap(libmapfilename);
1890  deplibs = gInterpreter->GetSharedLibDeps(moduleBasename);
1891  }
1892  } else {
1893  TString delim(" ");
1894  TObjArray *tokens = deplibs.Tokenize(delim);
1895  for (Int_t i = tokens->GetEntriesFast()-1; i > 0; i--) {
1896  const char *deplib = ((TObjString*)tokens->At(i))->GetName();
1897  if (strcmp(module,deplib)==0) {
1898  continue;
1899  }
1900  if (gDebug > 0)
1901  Info("Load", "loading dependent library %s for library %s",
1902  deplib, ((TObjString*)tokens->At(0))->GetName());
1903  if ((ret = Load(deplib, "", system)) < 0) {
1904  delete tokens;
1905  delete [] path;
1906  return ret;
1907  }
1908  }
1909  delete tokens;
1910  }
1911  if (!system) {
1912  // Mark the library in $ROOTSYS/lib as system.
1913  const char *dirname = DirName(path);
1914  system = R__MatchFilename(TROOT::GetLibDir(), dirname);
1915 
1916  if (!system) {
1917  system = R__MatchFilename(TROOT::GetBinDir(), dirname);
1918  }
1919  }
1920 
1923  gLibraryVersionMax *= 2;
1925  }
1926  ret = gInterpreter->Load(path, system);
1927  if (ret < 0) ret = -1;
1928  if (gDebug > 0)
1929  Info("Load", "loaded library %s, status %d", path, ret);
1930  if (ret == 0 && gLibraryVersion[gLibraryVersionIdx]) {
1931  int v = TROOT::ConvertVersionCode2Int(gLibraryVersion[gLibraryVersionIdx]);
1932  Error("Load", "version mismatch, %s = %d, ROOT = %d",
1933  path, v, gROOT->GetVersionInt());
1934  ret = -2;
1936  }
1937  gLibraryVersionIdx--;
1938  delete [] path;
1939  }
1940 
1941  if (!entry || !entry[0] || ret < 0) return ret;
1942 
1943  Func_t f = DynFindSymbol(module, entry);
1944  if (f) return 0;
1945  return -1;
1946 }
1947 
1948 ////////////////////////////////////////////////////////////////////////////////
1949 /// Find a dynamic library called lib using the system search paths.
1950 /// Appends known extensions if needed. Returned string must be deleted
1951 /// by the user!
1952 
1953 char *TSystem::DynamicPathName(const char *lib, Bool_t quiet /*=kFALSE*/)
1954 {
1955  TString sLib(lib);
1956  if (FindDynamicLibrary(sLib, quiet))
1957  return StrDup(sLib);
1958  return 0;
1959 }
1960 
1961 ////////////////////////////////////////////////////////////////////////////////
1962 /// Find a dynamic library using the system search paths. lib will be updated
1963 /// to contain the absolute filename if found. Returns lib if found, or NULL
1964 /// if a library called lib was not found.
1965 /// This function does not open the library.
1966 
1968 {
1969  AbstractMethod("FindDynamicLibrary");
1970  return 0;
1971 }
1972 
1973 ////////////////////////////////////////////////////////////////////////////////
1974 /// Find specific entry point in specified library. Specify "*" for lib
1975 /// to search in all libraries.
1976 
1977 Func_t TSystem::DynFindSymbol(const char * /*lib*/, const char *entry)
1978 {
1979  return (Func_t) gInterpreter->FindSym(entry);
1980 }
1981 
1982 ////////////////////////////////////////////////////////////////////////////////
1983 /// Unload a shared library.
1984 
1985 void TSystem::Unload(const char *module)
1986 {
1987  char *path;
1988  if ((path = DynamicPathName(module))) {
1989  gInterpreter->UnloadFile(path);
1990  delete [] path;
1991  }
1992 }
1993 
1994 ////////////////////////////////////////////////////////////////////////////////
1995 /// List symbols in a shared library.
1996 
1997 void TSystem::ListSymbols(const char *, const char *)
1998 {
1999  AbstractMethod("ListSymbols");
2000 }
2001 
2002 ////////////////////////////////////////////////////////////////////////////////
2003 /// List all loaded shared libraries. Regexp is a wildcard expression,
2004 /// see TRegexp::MakeWildcard.
2005 
2006 void TSystem::ListLibraries(const char *regexp)
2007 {
2008  TString libs = GetLibraries(regexp);
2009  TRegexp separator("[^ \\t\\s]+");
2010  TString s;
2011  Ssiz_t start = 0, index = 0, end = 0;
2012  int i = 0;
2013 
2014  Printf(" ");
2015  Printf("Loaded shared libraries");
2016  Printf("=======================");
2017 
2018  while ((start < libs.Length()) && (index != kNPOS)) {
2019  index = libs.Index(separator, &end, start);
2020  if (index >= 0) {
2021  s = libs(index, end);
2022  if (s.BeginsWith("-")) {
2023  if (s.BeginsWith("-l")) {
2024  Printf("%s", s.Data());
2025  i++;
2026  }
2027  } else {
2028  Printf("%s", s.Data());
2029  i++;
2030  }
2031  }
2032  start += end+1;
2033  }
2034 
2035  Printf("-----------------------");
2036  Printf("%d libraries loaded", i);
2037  Printf("=======================");
2038 }
2039 
2040 ////////////////////////////////////////////////////////////////////////////////
2041 /// Return the thread local storage for the custom last error message
2042 
2044 {
2045  TTHREAD_TLS_DECL( TString, gLastErrorString);
2046  return gLastErrorString;
2047 }
2048 
2049 ////////////////////////////////////////////////////////////////////////////////
2050 /// Return the thread local storage for the custom last error message
2051 
2053 {
2054  return const_cast<TSystem*>(this)->GetLastErrorString();
2055 }
2056 
2057 ////////////////////////////////////////////////////////////////////////////////
2058 /// Get list of shared libraries loaded at the start of the executable.
2059 /// Returns 0 in case list cannot be obtained or in case of error.
2060 
2062 {
2063  return 0;
2064 }
2065 
2066 ////////////////////////////////////////////////////////////////////////////////
2067 /// Return a space separated list of loaded shared libraries.
2068 /// Regexp is a wildcard expression, see TRegexp::MakeWildcard.
2069 /// This list is of a format suitable for a linker, i.e it may contain
2070 /// -Lpathname and/or -lNameOfLib.
2071 /// Option can be any of:
2072 /// - S: shared libraries loaded at the start of the executable, because
2073 /// they were specified on the link line.
2074 /// - D: shared libraries dynamically loaded after the start of the program.
2075 /// For MacOS only:
2076 /// - L: list the .dylib rather than the .so (this is intended for linking)
2077 /// This options is not the default
2078 
2079 const char *TSystem::GetLibraries(const char *regexp, const char *options,
2080  Bool_t isRegexp)
2081 {
2082  fListLibs.Clear();
2083 
2084  TString libs;
2085  TString opt(options);
2086  Bool_t so2dylib = (opt.First('L') != kNPOS);
2087  if (so2dylib)
2088  opt.ReplaceAll("L", "");
2089 
2090  if (opt.IsNull() || opt.First('D') != kNPOS)
2091  libs += gInterpreter->GetSharedLibs();
2092 
2093  // Cint currently register all libraries that
2094  // are loaded and have a dictionary in them, this
2095  // includes all the libraries that are included
2096  // in the list of (hard) linked libraries.
2097 
2098  TString slinked;
2099  const char *linked;
2100  if ((linked = GetLinkedLibraries())) {
2101  if (fLinkedLibs != LINKEDLIBS) {
2102  // This is not the default value, we need to keep the custom part.
2103  TString custom = fLinkedLibs;
2104  custom.ReplaceAll(LINKEDLIBS,linked);
2105  if (custom == fLinkedLibs) {
2106  // no replacement done, let's append linked
2107  slinked.Append(linked);
2108  slinked.Append(" ");
2109  }
2110  slinked.Append(custom);
2111  } else {
2112  slinked.Append(linked);
2113  }
2114  } else {
2115  slinked.Append(fLinkedLibs);
2116  }
2117 
2118  if (opt.IsNull() || opt.First('S') != kNPOS) {
2119  // We are done, the statically linked libraries are already included.
2120  if (libs.Length() == 0) {
2121  libs = slinked;
2122  } else {
2123  // We need to add the missing linked library
2124 
2125  static TString lastLinked;
2126  static TString lastAddMissing;
2127  if ( lastLinked != slinked ) {
2128  // Recalculate only if there was a change.
2129  static TRegexp separator("[^ \\t\\s]+");
2130  lastLinked = slinked;
2131  lastAddMissing.Clear();
2132 
2133  Ssiz_t start, index, end;
2134  start = index = end = 0;
2135 
2136  while ((start < slinked.Length()) && (index != kNPOS)) {
2137  index = slinked.Index(separator,&end,start);
2138  if (index >= 0) {
2139  TString sub = slinked(index,end);
2140  if (sub[0]=='-' && sub[1]=='L') {
2141  lastAddMissing.Prepend(" ");
2142  lastAddMissing.Prepend(sub);
2143  } else {
2144  if (libs.Index(sub) == kNPOS) {
2145  lastAddMissing.Prepend(" ");
2146  lastAddMissing.Prepend(sub);
2147  }
2148  }
2149  }
2150  start += end+1;
2151  }
2152  }
2153  libs.Prepend(lastAddMissing);
2154  }
2155  } else if (libs.Length() != 0) {
2156  // Let remove the statically linked library
2157  // from the list.
2158  static TRegexp separator("[^ \\t\\s]+");
2159  Ssiz_t start, index, end;
2160  start = index = end = 0;
2161 
2162  while ((start < slinked.Length()) && (index != kNPOS)) {
2163  index = slinked.Index(separator,&end,start);
2164  if (index >= 0) {
2165  TString sub = slinked(index,end);
2166  if (sub[0]!='-' && sub[1]!='L') {
2167  libs.ReplaceAll(sub,"");
2168  }
2169  }
2170  start += end+1;
2171  }
2172  libs = libs.Strip(TString::kBoth);
2173  }
2174 
2175  // Select according to regexp
2176  if (regexp && *regexp) {
2177  static TRegexp separator("[^ \\t\\s]+");
2178  TRegexp user_re(regexp, kTRUE);
2179  TString s;
2180  Ssiz_t start, index, end;
2181  start = index = end = 0;
2182 
2183  while ((start < libs.Length()) && (index != kNPOS)) {
2184  index = libs.Index(separator,&end,start);
2185  if (index >= 0) {
2186  s = libs(index,end);
2187  if ((isRegexp && s.Index(user_re) != kNPOS) ||
2188  (!isRegexp && s.Index(regexp) != kNPOS)) {
2189  if (!fListLibs.IsNull())
2190  fListLibs.Append(" ");
2191  fListLibs.Append(s);
2192  }
2193  }
2194  start += end+1;
2195  }
2196  } else
2197  fListLibs = libs;
2198 
2199 #if defined(R__MACOSX)
2200 // We need to remove the libraries that are dynamically loaded and not linked
2201 {
2202  TString libs2 = fListLibs;
2203  TString maclibs;
2204 
2205  static TRegexp separator("[^ \\t\\s]+");
2206  static TRegexp dynload("/lib-dynload/");
2207 
2208  Ssiz_t start, index, end;
2209  start = index = end = 0;
2210 
2211  while ((start < libs2.Length()) && (index != kNPOS)) {
2212  index = libs2.Index(separator, &end, start);
2213  if (index >= 0) {
2214  TString s = libs2(index, end);
2215  if (s.Index(dynload) == kNPOS) {
2216  if (!maclibs.IsNull()) maclibs.Append(" ");
2217  maclibs.Append(s);
2218  }
2219  }
2220  start += end+1;
2221  }
2222  fListLibs = maclibs;
2223 }
2224 #endif
2225 
2226 #if defined(R__MACOSX) && !defined(MAC_OS_X_VERSION_10_5)
2227  if (so2dylib) {
2228  TString libs2 = fListLibs;
2229  TString maclibs;
2230 
2231  static TRegexp separator("[^ \\t\\s]+");
2232  static TRegexp user_so("\\.so$");
2233 
2234  Ssiz_t start, index, end;
2235  start = index = end = 0;
2236 
2237  while ((start < libs2.Length()) && (index != kNPOS)) {
2238  index = libs2.Index(separator, &end, start);
2239  if (index >= 0) {
2240  // Change .so into .dylib and remove the
2241  // path info if it is not accessible
2242  TString s = libs2(index, end);
2243  if (s.Index(user_so) != kNPOS) {
2244  s.ReplaceAll(".so",".dylib");
2245  if ( GetPathInfo( s, 0, (Long_t*)0, 0, 0 ) != 0 ) {
2246  s.Replace( 0, s.Last('/')+1, 0, 0);
2247  s.Replace( 0, s.Last('\\')+1, 0, 0);
2248  }
2249  }
2250  if (!maclibs.IsNull()) maclibs.Append(" ");
2251  maclibs.Append(s);
2252  }
2253  start += end+1;
2254  }
2255  fListLibs = maclibs;
2256  }
2257 #endif
2258 
2259  return fListLibs;
2260 }
2261 
2262 //---- RPC ---------------------------------------------------------------------
2263 
2264 ////////////////////////////////////////////////////////////////////////////////
2265 /// Get Internet Protocol (IP) address of host.
2266 
2268 {
2269  AbstractMethod("GetHostByName");
2270  return TInetAddress();
2271 }
2272 
2273 ////////////////////////////////////////////////////////////////////////////////
2274 /// Get Internet Protocol (IP) address of remote host and port #.
2275 
2277 {
2278  AbstractMethod("GetPeerName");
2279  return TInetAddress();
2280 }
2281 
2282 ////////////////////////////////////////////////////////////////////////////////
2283 /// Get Internet Protocol (IP) address of host and port #.
2284 
2286 {
2287  AbstractMethod("GetSockName");
2288  return TInetAddress();
2289 }
2290 
2291 ////////////////////////////////////////////////////////////////////////////////
2292 /// Get port # of internet service.
2293 
2294 int TSystem::GetServiceByName(const char *)
2295 {
2296  AbstractMethod("GetServiceByName");
2297  return -1;
2298 }
2299 
2300 ////////////////////////////////////////////////////////////////////////////////
2301 /// Get name of internet service.
2302 
2304 {
2305  AbstractMethod("GetServiceByPort");
2306  return 0;
2307 }
2308 
2309 ////////////////////////////////////////////////////////////////////////////////
2310 /// Open a connection to another host.
2311 
2312 int TSystem::OpenConnection(const char*, int, int, const char*)
2313 {
2314  AbstractMethod("OpenConnection");
2315  return -1;
2316 }
2317 
2318 ////////////////////////////////////////////////////////////////////////////////
2319 /// Announce TCP/IP service.
2320 
2322 {
2323  AbstractMethod("AnnounceTcpService");
2324  return -1;
2325 }
2326 
2327 ////////////////////////////////////////////////////////////////////////////////
2328 /// Announce UDP service.
2329 
2331 {
2332  AbstractMethod("AnnounceUdpService");
2333  return -1;
2334 }
2335 
2336 ////////////////////////////////////////////////////////////////////////////////
2337 /// Announce unix domain service.
2338 
2340 {
2341  AbstractMethod("AnnounceUnixService");
2342  return -1;
2343 }
2344 
2345 ////////////////////////////////////////////////////////////////////////////////
2346 /// Announce unix domain service.
2347 
2348 int TSystem::AnnounceUnixService(const char *, int)
2349 {
2350  AbstractMethod("AnnounceUnixService");
2351  return -1;
2352 }
2353 
2354 ////////////////////////////////////////////////////////////////////////////////
2355 /// Accept a connection.
2356 
2358 {
2359  AbstractMethod("AcceptConnection");
2360  return -1;
2361 }
2362 
2363 ////////////////////////////////////////////////////////////////////////////////
2364 /// Close socket connection.
2365 
2367 {
2368  AbstractMethod("CloseConnection");
2369 }
2370 
2371 ////////////////////////////////////////////////////////////////////////////////
2372 /// Receive exactly length bytes into buffer. Use opt to receive out-of-band
2373 /// data or to have a peek at what is in the buffer (see TSocket).
2374 
2375 int TSystem::RecvRaw(int, void *, int, int)
2376 {
2377  AbstractMethod("RecvRaw");
2378  return -1;
2379 }
2380 
2381 ////////////////////////////////////////////////////////////////////////////////
2382 /// Send exactly length bytes from buffer. Use opt to send out-of-band
2383 /// data (see TSocket).
2384 
2385 int TSystem::SendRaw(int, const void *, int, int)
2386 {
2387  AbstractMethod("SendRaw");
2388  return -1;
2389 }
2390 
2391 ////////////////////////////////////////////////////////////////////////////////
2392 /// Receive a buffer headed by a length indicator.
2393 
2394 int TSystem::RecvBuf(int, void *, int)
2395 {
2396  AbstractMethod("RecvBuf");
2397  return -1;
2398 }
2399 
2400 ////////////////////////////////////////////////////////////////////////////////
2401 /// Send a buffer headed by a length indicator.
2402 
2403 int TSystem::SendBuf(int, const void *, int)
2404 {
2405  AbstractMethod("SendBuf");
2406  return -1;
2407 }
2408 
2409 ////////////////////////////////////////////////////////////////////////////////
2410 /// Set socket option.
2411 
2412 int TSystem::SetSockOpt(int, int, int)
2413 {
2414  AbstractMethod("SetSockOpt");
2415  return -1;
2416 }
2417 
2418 ////////////////////////////////////////////////////////////////////////////////
2419 /// Get socket option.
2420 
2421 int TSystem::GetSockOpt(int, int, int*)
2422 {
2423  AbstractMethod("GetSockOpt");
2424  return -1;
2425 }
2426 
2427 //---- System, CPU and Memory info ---------------------------------------------
2428 
2429 ////////////////////////////////////////////////////////////////////////////////
2430 /// Returns static system info, like OS type, CPU type, number of CPUs
2431 /// RAM size, etc into the SysInfo_t structure. Returns -1 in case of error,
2432 /// 0 otherwise.
2433 
2435 {
2436  AbstractMethod("GetSysInfo");
2437  return -1;
2438 }
2439 
2440 ////////////////////////////////////////////////////////////////////////////////
2441 /// Returns cpu load average and load info into the CpuInfo_t structure.
2442 /// Returns -1 in case of error, 0 otherwise. Use sampleTime to set the
2443 /// interval over which the CPU load will be measured, in ms (default 1000).
2444 
2446 {
2447  AbstractMethod("GetCpuInfo");
2448  return -1;
2449 }
2450 
2451 ////////////////////////////////////////////////////////////////////////////////
2452 /// Returns ram and swap memory usage info into the MemInfo_t structure.
2453 /// Returns -1 in case of error, 0 otherwise.
2454 
2456 {
2457  AbstractMethod("GetMemInfo");
2458  return -1;
2459 }
2460 
2461 ////////////////////////////////////////////////////////////////////////////////
2462 /// Returns cpu and memory used by this process into the ProcInfo_t structure.
2463 /// Returns -1 in case of error, 0 otherwise.
2464 
2466 {
2467  AbstractMethod("GetProcInfo");
2468  return -1;
2469 }
2470 
2471 //---- Script Compiler ---------------------------------------------------------
2472 
2473 void AssignAndDelete(TString& target, char *tobedeleted)
2474 {
2475  // Assign the char* value to the TString and then delete it.
2476 
2477  target = tobedeleted;
2478  delete [] tobedeleted;
2479 }
2480 
2481 #ifdef WIN32
2482 
2483 static TString R__Exec(const char *cmd)
2484 {
2485  // Execute a command and return the stdout in a string.
2486 
2487  FILE * f = gSystem->OpenPipe(cmd,"r");
2488  if (!f) {
2489  return "";
2490  }
2491  TString result;
2492 
2493  char x;
2494  while ((x = fgetc(f))!=EOF ) {
2495  if (x=='\n' || x=='\r') break;
2496  result += x;
2497  }
2498 
2499  fclose(f);
2500  return result;
2501 }
2502 
2503 static void R__FixLink(TString &cmd)
2504 {
2505  // Replace the call to 'link' by a full path name call based on where cl.exe is.
2506  // This prevents us from using inadvertently the link.exe provided by cygwin.
2507 
2508  // check if link is the microsoft one...
2509  TString res = R__Exec("link 2>&1");
2510  if (res.Length()) {
2511  if (res.Contains("Microsoft (R) Incremental Linker"))
2512  return;
2513  }
2514  // else check availability of cygpath...
2515  res = R__Exec("cygpath . 2>&1");
2516  if (res.Length()) {
2517  if (res != ".")
2518  return;
2519  }
2520 
2521  res = R__Exec("which cl.exe 2>&1|grep cl|sed 's,cl\\.exe$,link\\.exe,' 2>&1");
2522  if (res.Length()) {
2523  res = R__Exec(Form("cygpath -w '%s' 2>&1",res.Data()));
2524  if (res.Length()) {
2525  cmd.ReplaceAll(" link ",Form(" \"%s\" ",res.Data()));
2526  }
2527  }
2528 }
2529 #endif
2530 
2531 #ifndef WIN32
2532 static void R__AddPath(TString &target, const TString &path) {
2533  target += path;
2534 }
2535 #else
2536 static void R__AddPath(TString &target, const TString &path) {
2537  if (path.Length() > 2 && path[1]==':') {
2538  target += TString::Format("/cygdrive/%c",path[0]) + path(2,path.Length()-2);
2539  } else {
2540  target += path;
2541  }
2542 }
2543 #endif
2544 
2545 #ifndef WIN32
2546 static void R__WriteDependencyFile(const TString & build_loc, const TString &depfilename, const TString &filename, const TString &library, const TString &libname,
2547  const TString &extension, const char *version_var_prefix, const TString &includes, const TString &defines, const TString &incPath)
2548 #else
2549 static void R__WriteDependencyFile(const TString &build_loc, const TString &depfilename, const TString &filename, const TString &library, const TString &libname,
2550  const TString &extension, const char *version_var_prefix, const TString &includes, const TString &defines, const TString &incPath)
2551 #endif
2552 {
2553  // Generate the dependency via standard output, not searching the
2554  // standard include directories,
2555 
2556 #ifndef WIN32
2557  const char * stderrfile = "/dev/null";
2558 #else
2559  TString stderrfile;
2560  AssignAndDelete( stderrfile, gSystem->ConcatFileName(build_loc,"stderr.tmp") );
2561 #endif
2562  TString bakdepfilename = depfilename + ".bak";
2563 
2564 #ifdef WIN32
2565  TString touch = "echo # > "; touch += "\"" + depfilename + "\"";
2566 #else
2567  TString touch = "echo > "; touch += "\"" + depfilename + "\"";
2568 #endif
2569  TString builddep = "rmkdepend";
2570  gSystem->PrependPathName(TROOT::GetBinDir(), builddep);
2571  builddep += " \"-f";
2572  builddep += depfilename;
2573  builddep += "\" -o_" + extension + "." + gSystem->GetSoExt() + " ";
2574  if (build_loc.BeginsWith(gSystem->WorkingDirectory())) {
2575  Int_t len = strlen(gSystem->WorkingDirectory());
2576  if ( build_loc.Length() > (len+1) ) {
2577  builddep += " \"-p";
2578  if (build_loc[len] == '/' || build_loc[len+1] != '\\' ) {
2579  // Since the path is now ran through TSystem::ExpandPathName the single \ is also possible.
2580  R__AddPath(builddep, build_loc.Data() + len + 1 );
2581  } else {
2582  // Case of dir\\name
2583  R__AddPath(builddep, build_loc.Data() + len + 2 );
2584  }
2585  builddep += "/\" ";
2586  }
2587  } else {
2588  builddep += " \"-p";
2589  R__AddPath(builddep, build_loc);
2590  builddep += "/\" ";
2591  }
2592  builddep += " -Y -- ";
2593  TString rootsysInclude = TROOT::GetIncludeDir();
2594  builddep += " \"-I"+rootsysInclude+"\" "; // cflags
2595  builddep += includes;
2596  builddep += defines;
2597  builddep += " -- \"";
2598  builddep += filename;
2599  builddep += "\" ";
2600  TString targetname;
2601  if (library.BeginsWith(gSystem->WorkingDirectory())) {
2602  Int_t len = strlen(gSystem->WorkingDirectory());
2603  if ( library.Length() > (len+1) ) {
2604  if (library[len] == '/' || library[len+1] != '\\' ) {
2605  targetname = library.Data() + len + 1;
2606  } else {
2607  targetname = library.Data() + len + 2;
2608  }
2609  } else {
2610  targetname = library;
2611  }
2612  } else {
2613  targetname = library;
2614  }
2615  builddep += " \"";
2616  builddep += "-t";
2617  R__AddPath(builddep, targetname);
2618  builddep += "\" > ";
2619  builddep += stderrfile;
2620  builddep += " 2>&1 ";
2621 
2622  TString adddictdep = "echo ";
2623  R__AddPath(adddictdep,targetname);
2624  adddictdep += ": ";
2625 #if defined(R__HAS_CLING_DICTVERSION)
2626  {
2627  char *clingdictversion = gSystem->Which(incPath,"clingdictversion.h");
2628  if (clingdictversion) {
2629  R__AddPath(adddictdep,clingdictversion);
2630  adddictdep += " ";
2631  delete [] clingdictversion;
2632  } else {
2633  R__AddPath(adddictdep,rootsysInclude+"/clingdictversion.h ");
2634  }
2635  }
2636 #endif
2637  {
2638  const char *dictHeaders[] = { "RVersion.h", "RConfig.h", "TClass.h",
2639  "TDictAttributeMap.h","TInterpreter.h","TROOT.h","TBuffer.h",
2640  "TMemberInspector.h","TError.h","RtypesImp.h","TIsAProxy.h",
2641  "TFileMergeInfo.h","TCollectionProxyInfo.h"};
2642 
2643  for (unsigned int h=0; h < sizeof(dictHeaders)/sizeof(dictHeaders[0]); ++h)
2644  {
2645  char *rootVersion = gSystem->Which(incPath,dictHeaders[h]);
2646  if (rootVersion) {
2647  R__AddPath(adddictdep,rootVersion);
2648  adddictdep += " ";
2649  delete [] rootVersion;
2650  } else {
2651  R__AddPath(adddictdep,rootsysInclude + "/" + dictHeaders[h]);
2652  }
2653  }
2654  }
2655  {
2656  // Add dependency on rootcling.
2657  char *rootCling = gSystem->Which(gSystem->Getenv("PATH"),"rootcling");
2658  if (rootCling) {
2659  R__AddPath(adddictdep,rootCling);
2660  adddictdep += " ";
2661  delete [] rootCling;
2662  }
2663  }
2664  adddictdep += " >> \""+depfilename+"\"";
2665 
2666  TString addversiondep( "echo ");
2667  addversiondep += libname + version_var_prefix + " \"" + ROOT_RELEASE + "\" >> \""+depfilename+"\"";
2668 
2669  if (gDebug > 4) {
2670  ::Info("ACLiC", "%s", touch.Data());
2671  ::Info("ACLiC", "%s", builddep.Data());
2672  ::Info("ACLiC", "%s", adddictdep.Data());
2673  }
2674 
2675  Int_t depbuilt = !gSystem->Exec(touch);
2676  if (depbuilt) depbuilt = !gSystem->Exec(builddep);
2677  if (depbuilt) depbuilt = !gSystem->Exec(adddictdep);
2678  if (depbuilt) depbuilt = !gSystem->Exec(addversiondep);
2679 
2680  if (!depbuilt) {
2681  ::Warning("ACLiC","Failed to generate the dependency file for %s",
2682  library.Data());
2683  } else {
2684 #ifdef WIN32
2685  gSystem->Unlink(stderrfile);
2686 #endif
2687  gSystem->Unlink(bakdepfilename);
2688  }
2689 }
2690 
2691 ////////////////////////////////////////////////////////////////////////////////
2692 /// This method compiles and loads a shared library containing
2693 /// the code from the file "filename".
2694 ///
2695 /// The return value is true (1) in case of success and false (0)
2696 /// in case of error.
2697 ///
2698 /// The possible options are:
2699 /// - k : keep the shared library after the session end.
2700 /// - f : force recompilation.
2701 /// - g : compile with debug symbol
2702 /// - O : optimized the code
2703 /// - c : compile only, do not attempt to load the library.
2704 /// - s : silence all informational output
2705 /// - v : output all information output
2706 /// - d : debug ACLiC, keep all the output files.
2707 /// - - : if buildir is set, use a flat structure (see buildir below)
2708 ///
2709 /// If library_specified is specified, CompileMacro generates the file
2710 /// "library_specified".soext where soext is the shared library extension for
2711 /// the current platform.
2712 ///
2713 /// If build_dir is specified, it is used as an alternative 'root' for the
2714 /// generation of the shared library. The library is stored in a sub-directories
2715 /// of 'build_dir' including the full pathname of the script unless a flat
2716 /// directory structure is requested ('-' option). With the '-' option the libraries
2717 /// are created directly in the directory 'build_dir'; in particular this means that
2718 /// 2 scripts with the same name in different source directory will over-write each
2719 /// other's library.
2720 /// See also TSystem::SetBuildDir.
2721 ///
2722 /// If dirmode is not zero and we need to create the target directory, the
2723 /// file mode bit will be change to 'dirmode' using chmod.
2724 ///
2725 /// If library_specified is not specified, CompileMacro generate a default name
2726 /// for library by taking the name of the file "filename" but replacing the
2727 /// dot before the extension by an underscore and by adding the shared
2728 /// library extension for the current platform.
2729 /// For example on most platform, hsimple.cxx will generate hsimple_cxx.so
2730 ///
2731 /// It uses the directive fMakeSharedLibs to create a shared library.
2732 /// If loading the shared library fails, it tries to output a list of missing
2733 /// symbols by creating an executable (on some platforms like OSF, this does
2734 /// not HAVE to be an executable) containing the script. It uses the
2735 /// directive fMakeExe to do so.
2736 /// For both directives, before passing them to TSystem::Exec, it expands the
2737 /// variables $SourceFiles, $SharedLib, $LibName, $IncludePath, $LinkedLibs,
2738 /// $DepLibs, $ExeName and $ObjectFiles. See SetMakeSharedLib() for more
2739 /// information on those variables.
2740 ///
2741 /// This method is used to implement the following feature:
2742 ///
2743 /// Synopsis:
2744 ///
2745 /// The purpose of this addition is to allow the user to use an external
2746 /// compiler to create a shared library from its C++ macro (scripts).
2747 /// Currently in order to execute a script, a user has to type at the root
2748 /// prompt
2749 /// ~~~ {.cpp}
2750 /// .X myfunc.C(arg1,arg2)
2751 /// ~~~
2752 /// We allow them to type:
2753 /// ~~~ {.cpp}
2754 /// .X myfunc.C++(arg1,arg2)
2755 /// ~~~
2756 /// or
2757 /// ~~~ {.cpp}
2758 /// .X myfunc.C+(arg1,arg2)
2759 /// ~~~
2760 /// In which case an external compiler will be called to create a shared
2761 /// library. This shared library will then be loaded and the function
2762 /// myfunc will be called with the two arguments. With '++' the shared library
2763 /// is always recompiled. With '+' the shared library is recompiled only
2764 /// if it does not exist yet or the macro file is newer than the shared
2765 /// library.
2766 ///
2767 /// Of course the + and ++ notation is supported in similar way for .x and .L.
2768 ///
2769 /// Through the function TSystem::SetMakeSharedLib(), the user will be able to
2770 /// indicate, with shell commands, how to build a shared library (a good
2771 /// default will be provided). The most common change, namely where to find
2772 /// header files, will be available through the function
2773 /// TSystem::SetIncludePath().
2774 /// A good default will be provided so that a typical user session should be at
2775 /// most:
2776 /// ~~~ {.cpp}
2777 /// root[1] gSystem->SetIncludePath("-I$ROOTSYS/include
2778 /// -I$HOME/mypackage/include");
2779 /// root[2] .x myfunc.C++(10,20);
2780 /// ~~~
2781 /// The user may sometimes try to compile a script before it has loaded all the
2782 /// needed shared libraries. In this case we want to be helpfull and output a
2783 /// list of the unresolved symbols. So if the loading of the created shared
2784 /// library fails, we will try to build a executable that contains the
2785 /// script. The linker should then output a list of missing symbols.
2786 ///
2787 /// To support this we provide a TSystem::SetMakeExe() function, that sets the
2788 /// directive telling how to create an executable. The loader will need
2789 /// to be informed of all the libraries available. The information about
2790 /// the libraries that has been loaded by .L and TSystem::Load() is accesible
2791 /// to the script compiler. However, the information about
2792 /// the libraries that have been selected at link time by the application
2793 /// builder (like the root libraries for root.exe) are not available and need
2794 /// to be explicitly listed in fLinkedLibs (either by default or by a call to
2795 /// TSystem::SetLinkedLibs()).
2796 ///
2797 /// To simplify customization we could also add to the .rootrc support for the
2798 /// variables
2799 /// ~~~ {.cpp}
2800 /// Unix.*.Root.IncludePath: -I$ROOTSYS/include
2801 /// WinNT.*.Root.IncludePath: -I%ROOTSYS%/include
2802 ///
2803 /// Unix.*.Root.LinkedLibs: -L$ROOTSYS/lib -lBase ....
2804 /// WinNT.*.Root.LinkedLibs: %ROOTSYS%/lib/*.lib msvcrt.lib ....
2805 /// ~~~
2806 /// And also support for MakeSharedLibs() and MakeExe().
2807 ///
2808 /// (the ... have to be replaced by the actual values and are here only to
2809 /// shorten this comment).
2810 
2811 int TSystem::CompileMacro(const char *filename, Option_t *opt,
2812  const char *library_specified,
2813  const char *build_dir,
2814  UInt_t dirmode)
2815 {
2816  static const char *version_var_prefix = "__ROOTBUILDVERSION=";
2817 
2818  // ======= Analyze the options
2819  Bool_t keep = kFALSE;
2820  Bool_t recompile = kFALSE;
2821  EAclicMode mode = fAclicMode;
2822  Bool_t loadLib = kTRUE;
2823  Bool_t withInfo = kTRUE;
2824  Bool_t verbose = kFALSE;
2825  Bool_t internalDebug = kFALSE;
2826  if (opt) {
2827  keep = (strchr(opt,'k')!=0);
2828  recompile = (strchr(opt,'f')!=0);
2829  if (strchr(opt,'O')!=0) {
2830  mode = kOpt;
2831  }
2832  if (strchr(opt,'g')!=0) {
2833  mode = kDebug;
2834  }
2835  if (strchr(opt,'c')!=0) {
2836  loadLib = kFALSE;
2837  }
2838  withInfo = strchr(opt, 's') == 0;
2839  verbose = strchr(opt, 'v') != 0;
2840  internalDebug = strchr(opt, 'd') != 0;
2841  }
2842  if (mode==kDefault) {
2843  TString rootbuild = ROOTBUILD;
2844  if (rootbuild.Index("debug",0,TString::kIgnoreCase)==kNPOS) {
2845  mode=kOpt;
2846  } else {
2847  mode=kDebug;
2848  }
2849  }
2850  UInt_t verboseLevel = verbose ? 7 : gDebug;
2851  Bool_t flatBuildDir = (fAclicProperties & kFlatBuildDir) || (strchr(opt,'-')!=0);
2852 
2853  // if non-zero, build_loc indicates where to build the shared library.
2854  TString build_loc = ExpandFileName(GetBuildDir());
2855  if (build_dir && strlen(build_dir)) build_loc = build_dir;
2856  if (build_loc == ".") {
2857  build_loc = WorkingDirectory();
2858  } else if (build_loc.Length() && (!IsAbsoluteFileName(build_loc)) ) {
2859  AssignAndDelete( build_loc , ConcatFileName( WorkingDirectory(), build_loc ) );
2860  }
2861 
2862  // Get the include directory list in the dir1:dir2:dir3 format
2863  // [Used for generating the .d file and to look for header files for
2864  // the linkdef file]
2865  TString incPath = GetIncludePath(); // of the form -Idir1 -Idir2 -Idir3
2866  incPath.Append(":").Prepend(" ");
2867  if (gEnv) {
2868  TString fromConfig = gEnv->GetValue("ACLiC.IncludePaths","");
2869  incPath.Append(fromConfig);
2870  }
2871  incPath.ReplaceAll(" -I",":"); // of form :dir1 :dir2:dir3
2872  while ( incPath.Index(" :") != -1 ) {
2873  incPath.ReplaceAll(" :",":");
2874  }
2875  incPath.Prepend(":.:");
2876  incPath.Prepend(WorkingDirectory());
2877 
2878  // ======= Get the right file names for the dictionary and the shared library
2879  TString expFileName(filename);
2880  ExpandPathName( expFileName );
2881  TString library = expFileName;
2882  if (! IsAbsoluteFileName(library) )
2883  {
2884  const char *whichlibrary = Which(incPath,library);
2885  if (whichlibrary) {
2886  library = whichlibrary;
2887  delete [] whichlibrary;
2888  } else {
2889  ::Error("ACLiC","The file %s can not be found in the include path: %s",filename,incPath.Data());
2890  return kFALSE;
2891  }
2892  } else {
2893  if (gSystem->AccessPathName(library)) {
2894  ::Error("ACLiC","The file %s can not be found.",filename);
2895  return kFALSE;
2896  }
2897  }
2898  { // Remove multiple '/' characters, rootcling treats them as comments.
2899  Ssiz_t pos = 0;
2900  while ((pos = library.Index("//", 2, pos, TString::kExact)) != kNPOS) {
2901  library.Remove(pos, 1);
2902  }
2903  }
2904  TString filename_fullpath = library;
2905 
2906  TString file_dirname = DirName( filename_fullpath );
2907  // For some probably good reason, DirName on Windows returns the 'name' of
2908  // the directory, omitting the drive letter (even if there was one). In
2909  // consequence the result is not useable as a 'root directory', we need to
2910  // add the drive letter if there was one..
2911  if (library.Length()>1 && isalpha(library[0]) && library[1]==':') {
2912  file_dirname.Prepend(library(0,2));
2913  }
2914  TString file_location( file_dirname ); // Location of the script.
2915  incPath.Prepend( file_location + ":" );
2916 
2917  Ssiz_t dot_pos = library.Last('.');
2918  TString extension = library;
2919  extension.Replace( 0, dot_pos+1, 0 , 0);
2920  TString libname_noext = library;
2921  if (dot_pos>=0) libname_noext.Remove( dot_pos );
2922 
2923  // Extension of shared library is platform dependent!!
2924  library.Replace( dot_pos, library.Length()-dot_pos,
2925  TString("_") + extension + "." + fSoExt );
2926 
2927  TString libname ( BaseName( libname_noext ) );
2928  libname.Append("_").Append(extension);
2929 
2930  if (library_specified && strlen(library_specified) ) {
2931  // Use the specified name instead of the default
2932  libname = BaseName( library_specified );
2933  library = library_specified;
2934  ExpandPathName( library );
2935  if (! IsAbsoluteFileName(library) ) {
2936  AssignAndDelete( library , ConcatFileName( WorkingDirectory(), library ) );
2937  }
2938  library = TString(library) + "." + fSoExt;
2939  }
2940 
2941  TString libname_ext ( libname );
2942  libname_ext += "." + fSoExt;
2943 
2944  TString lib_dirname = DirName( library );
2945  // For some probably good reason, DirName on Windows returns the 'name' of
2946  // the directory, omitting the drive letter (even if there was one). In
2947  // consequence the result is not useable as a 'root directory', we need to
2948  // add the drive letter if there was one..
2949  if (library.Length()>1 && isalpha(library[0]) && library[1]==':') {
2950  lib_dirname.Prepend(library(0,2));
2951  }
2952  // Strip potential, somewhat redundant '/.' from the pathname ...
2953  if ( strncmp( &(lib_dirname[lib_dirname.Length()-2]), "/.", 2) == 0 ) {
2954  lib_dirname.Remove(lib_dirname.Length()-2);
2955  }
2956  if ( strncmp( &(lib_dirname[lib_dirname.Length()-2]), "\\.", 2) == 0 ) {
2957  lib_dirname.Remove(lib_dirname.Length()-2);
2958  }
2959  TString lib_location( lib_dirname );
2960  Bool_t mkdirFailed = kFALSE;
2961 
2962  if (build_loc.Length()==0) {
2963  build_loc = lib_location;
2964  } else {
2965  // Removes an existing disk specification from the names
2966  TRegexp disk_finder ("[A-z]:");
2967  Int_t pos = library.Index( disk_finder );
2968  if (pos==0) library.Remove(pos,3);
2969  pos = lib_location.Index( disk_finder );
2970  if (pos==0) lib_location.Remove(pos,3);
2971 
2972  if (flatBuildDir) {
2973  AssignAndDelete( library, ConcatFileName( build_loc, libname_ext) );
2974  } else {
2975  AssignAndDelete( library, ConcatFileName( build_loc, library) );
2976  }
2977 
2978  Bool_t canWriteBuild_loc = !gSystem->AccessPathName(build_loc,kWritePermission);
2979  TString build_loc_store( build_loc );
2980  if (!flatBuildDir) {
2981  AssignAndDelete( build_loc, ConcatFileName( build_loc, lib_location) );
2982  }
2983 
2984  if (gSystem->AccessPathName(build_loc,kFileExists)) {
2985  mkdirFailed = (0 != mkdir(build_loc, true));
2986  if (mkdirFailed && !canWriteBuild_loc) {
2987  // The mkdir failed __and__ we can not write to the target directory,
2988  // let make sure the error message will be about the target directory
2989  build_loc = build_loc_store;
2990  mkdirFailed = kFALSE;
2991  } else if (!mkdirFailed && dirmode!=0) {
2992  Chmod(build_loc,dirmode);
2993  }
2994  }
2995  }
2996 
2997  // ======= Check if the library need to loaded or compiled
2998  if ( gInterpreter->IsLoaded(expFileName) &&
2999  !gInterpreter->IsLoaded(library) ) {
3000  // the script has already been loaded in interpreted mode
3001  // Let's warn the user and unload it.
3002 
3003  if (withInfo) {
3004  ::Info("ACLiC","script has already been loaded in interpreted mode");
3005  ::Info("ACLiC","unloading %s and compiling it", filename);
3006  }
3007 
3008  if ( gInterpreter->UnloadFile( expFileName ) != 0 ) {
3009  // We can not unload it.
3010  return kFALSE;
3011  }
3012  }
3013 
3014  // Calculate the -I lines
3015  TString includes = GetIncludePath();
3016  includes.Prepend(' ');
3017 
3018  {
3019  // I need to replace the -Isomerelativepath by -I../ (or -I..\ on NT)
3020  TRegexp rel_inc(" -I[^\"/\\$%-][^:-]+");
3021  Int_t len,pos;
3022  pos = rel_inc.Index(includes,&len);
3023  while( len != 0 ) {
3024  TString sub = includes(pos,len);
3025  sub.Remove(0,3); // Remove ' -I'
3026  AssignAndDelete( sub, ConcatFileName( WorkingDirectory(), sub ) );
3027  sub.Prepend(" -I\"");
3028  sub.Chop(); // Remove trailing space (i.e between the -Is ...
3029  sub.Append("\" ");
3030  includes.Replace(pos,len,sub);
3031  pos = rel_inc.Index(includes,&len);
3032  }
3033  }
3034  {
3035  // I need to replace the -I"somerelativepath" by -I"$cwd/ (or -I"$cwd\ on NT)
3036  TRegexp rel_inc(" -I\"[^/\\$%-][^:-]+");
3037  Int_t len,pos;
3038  pos = rel_inc.Index(includes,&len);
3039  while( len != 0 ) {
3040  TString sub = includes(pos,len);
3041  sub.Remove(0,4); // Remove ' -I"'
3042  AssignAndDelete( sub, ConcatFileName( WorkingDirectory(), sub ) );
3043  sub.Prepend(" -I\"");
3044  includes.Replace(pos,len,sub);
3045  pos = rel_inc.Index(includes,&len);
3046  }
3047  }
3048  //includes += " -I\"" + build_loc;
3049  //includes += "\" -I\"";
3050  //includes += WorkingDirectory();
3051 // if (includes[includes.Length()-1] == '\\') {
3052 // // The current directory is (most likely) the root of a windows drive and
3053 // // has a trailing \ which would espace the quote if left by itself.
3054 // includes += '\\';
3055 // }
3056 // includes += "\"";
3057  if (gEnv) {
3058  TString fromConfig = gEnv->GetValue("ACLiC.IncludePaths","");
3059  includes.Append(" ").Append(fromConfig).Append(" ");
3060  }
3061 
3062  // Extract the -D for the dependency generation.
3063  TString defines = " ";
3064  {
3065  TString cmd = GetMakeSharedLib();
3066  TRegexp rel_def("-D[^\\s\\t\\n\\r]*");
3067  Int_t len,pos;
3068  pos = rel_def.Index(cmd,&len);
3069  while( len != 0 ) {
3070  defines += cmd(pos,len);
3071  defines += " ";
3072  pos = rel_def.Index(cmd,&len,pos+1);
3073  }
3074 
3075  }
3076 
3077  TString emergency_loc;
3078  {
3079  UserGroup_t *ug = gSystem->GetUserInfo(gSystem->GetUid());
3080  if (ug) {
3081  AssignAndDelete( emergency_loc, ConcatFileName( TempDirectory(), ug->fUser ) );
3082  delete ug;
3083  } else {
3084  emergency_loc = TempDirectory();
3085  }
3086  }
3087 
3088  Bool_t canWrite = !gSystem->AccessPathName(build_loc,kWritePermission);
3089 
3090  Bool_t modified = kFALSE;
3091 
3092  // Generate the dependency filename
3093  TString depdir = build_loc;
3094  TString depfilename;
3095  AssignAndDelete( depfilename, ConcatFileName(depdir, BaseName(libname_noext)) );
3096  depfilename += "_" + extension + ".d";
3097 
3098  if ( !recompile ) {
3099 
3100  Long_t lib_time, file_time;
3101 
3102  if ((gSystem->GetPathInfo( library, 0, (Long_t*)0, 0, &lib_time ) != 0) ||
3103  (gSystem->GetPathInfo( expFileName, 0, (Long_t*)0, 0, &file_time ) == 0 &&
3104  (lib_time < file_time))) {
3105 
3106  // the library does not exist or is older than the script.
3107  recompile = kTRUE;
3108  modified = kTRUE;
3109 
3110  } else {
3111 
3112  if ( gSystem->GetPathInfo( depfilename, 0,(Long_t*) 0, 0, &file_time ) != 0 ) {
3113  if (!canWrite) {
3114  depdir = emergency_loc;
3115  AssignAndDelete( depfilename, ConcatFileName(depdir, BaseName(libname_noext)) );
3116  depfilename += "_" + extension + ".d";
3117  }
3118  R__WriteDependencyFile(build_loc, depfilename, filename_fullpath, library, libname, extension, version_var_prefix, includes, defines, incPath);
3119  }
3120  }
3121 
3122  if (!modified) {
3123 
3124  // We need to check the dependencies
3125  FILE * depfile = fopen(depfilename.Data(),"r");
3126  if (depfile==0) {
3127  // there is no accessible dependency file, let's assume the library has been
3128  // modified
3129  modified = kTRUE;
3130  recompile = kTRUE;
3131 
3132  } else {
3133 
3134  TString version_var = libname + version_var_prefix;
3135 
3136  Int_t sz = 256;
3137  char *line = new char[sz];
3138  line[0] = 0;
3139 
3140  int c;
3141  Int_t current = 0;
3142  Int_t nested = 0;
3143  Bool_t hasversion = false;
3144 
3145  while ((c = fgetc(depfile)) != EOF) {
3146  if (c=='#') {
3147  // skip comment
3148  while ((c = fgetc(depfile)) != EOF) {
3149  if (c=='\n') {
3150  break;
3151  }
3152  }
3153  continue;
3154  }
3155  if (current && line[current-1]=='=' && strncmp(version_var.Data(),line,current)==0) {
3156 
3157  // The next word will be the version number.
3158  hasversion = kTRUE;
3159  line[0] = 0;
3160  current = 0;
3161  } else if (isspace(c) && !nested) {
3162  if (current) {
3163  if (line[current-1]!=':') {
3164  // ignore target
3165  line[current] = 0;
3166 
3167  Long_t filetime;
3168  if (hasversion) {
3169  modified |= strcmp(ROOT_RELEASE,line)!=0;
3170  hasversion = kFALSE;
3171  } else if ( gSystem->GetPathInfo( line, 0, (Long_t*)0, 0, &filetime ) == 0 ) {
3172  modified |= ( lib_time <= filetime );
3173  }
3174  }
3175  }
3176  current = 0;
3177  line[0] = 0;
3178  } else {
3179  if (current==sz-1) {
3180  sz = 2*sz;
3181  char *newline = new char[sz];
3182  strcpy(newline,line);
3183  delete [] line;
3184  line = newline;
3185  }
3186  if (c=='"') nested = !nested;
3187  else {
3188  line[current] = c;
3189  current++;
3190  }
3191  }
3192  }
3193  delete [] line;
3194  fclose(depfile);
3195  recompile = modified;
3196 
3197  }
3198 
3199  }
3200  }
3201 
3202  if ( gInterpreter->IsLoaded(library)
3203  || strlen(GetLibraries(library,"D",kFALSE)) != 0 ) {
3204  // The library has already been built and loaded.
3205 
3206  Bool_t reload = kFALSE;
3207  TNamed *libinfo = (TNamed*)fCompiled->FindObject(library);
3208  if (libinfo) {
3209  Long_t load_time = libinfo->GetUniqueID();
3210  Long_t lib_time;
3211  if ( gSystem->GetPathInfo( library, 0, (Long_t*)0, 0, &lib_time ) == 0
3212  && (lib_time>load_time)) {
3213  reload = kTRUE;
3214  }
3215  }
3216 
3217  if ( !recompile && reload ) {
3218 
3219  if (withInfo) {
3220  ::Info("ACLiC","%s has been modified and will be reloaded",
3221  libname.Data());
3222  }
3223  if ( gInterpreter->UnloadFile( library.Data() ) != 0 ) {
3224  // The library is being used. We can not unload it.
3225  return kFALSE;
3226  }
3227  if (libinfo) {
3228  fCompiled->Remove(libinfo);
3229  delete libinfo;
3230  libinfo = 0;
3231  }
3232  TNamed *k = new TNamed(library,library);
3233  Long_t lib_time;
3234  gSystem->GetPathInfo( library, 0, (Long_t*)0, 0, &lib_time );
3235  k->SetUniqueID(lib_time);
3236  if (!keep) k->SetBit(kMustCleanup);
3237  fCompiled->Add(k);
3238 
3239  return !gSystem->Load(library);
3240  }
3241 
3242  if (withInfo) {
3243  ::Info("ACLiC","%s script has already been compiled and loaded",
3244  modified ? "modified" : "unmodified");
3245  }
3246 
3247  if ( !recompile ) {
3248  return kTRUE;
3249  } else {
3250  if (withInfo) {
3251  ::Info("ACLiC","it will be regenerated and reloaded!");
3252  }
3253  if ( gInterpreter->UnloadFile( library.Data() ) != 0 ) {
3254  // The library is being used. We can not unload it.
3255  return kFALSE;
3256  }
3257  if (libinfo) {
3258  fCompiled->Remove(libinfo);
3259  delete libinfo;
3260  libinfo = 0;
3261  }
3262  Unlink(library);
3263  }
3264 
3265  }
3266 
3267  TString libmapfilename;
3268  AssignAndDelete( libmapfilename, ConcatFileName( build_loc, libname ) );
3269  libmapfilename += ".rootmap";
3270 #if (defined(R__MACOSX) && !defined(MAC_OS_X_VERSION_10_5)) || defined(R__WIN32)
3271  Bool_t produceRootmap = kTRUE;
3272 #else
3273  Bool_t produceRootmap = kFALSE;
3274 #endif
3275  Bool_t linkDepLibraries = !produceRootmap;
3276  if (gEnv) {
3277 #if (defined(R__MACOSX) && !defined(MAC_OS_X_VERSION_10_5))
3278  Int_t linkLibs = gEnv->GetValue("ACLiC.LinkLibs",2);
3279 #elif defined(R__WIN32)
3280  Int_t linkLibs = gEnv->GetValue("ACLiC.LinkLibs",3);
3281 #else
3282  Int_t linkLibs = gEnv->GetValue("ACLiC.LinkLibs",1);
3283 #endif
3284  produceRootmap = linkLibs & 0x2;
3285  linkDepLibraries = linkLibs & 0x1;
3286  }
3287 
3288  if (!recompile) {
3289  // The library already exist, let's just load it.
3290  if (loadLib) {
3291  TNamed *k = new TNamed(library,library);
3292  Long_t lib_time;
3293  gSystem->GetPathInfo( library, 0, (Long_t*)0, 0, &lib_time );
3294  k->SetUniqueID(lib_time);
3295  if (!keep) k->SetBit(kMustCleanup);
3296  fCompiled->Add(k);
3297 
3298  if (gInterpreter->GetSharedLibDeps(libname) == 0) {
3299  gInterpreter->LoadLibraryMap(libmapfilename);
3300  }
3301 
3302  return !gSystem->Load(library);
3303  }
3304  else return kTRUE;
3305  }
3306 
3307  if (!canWrite && recompile) {
3308 
3309  if (mkdirFailed) {
3310  ::Warning("ACLiC","Could not create the directory: %s",
3311  build_loc.Data());
3312  } else {
3313  ::Warning("ACLiC","%s is not writable!",
3314  build_loc.Data());
3315  }
3316  if (emergency_loc == build_dir ) {
3317  ::Error("ACLiC","%s is the last resort location (i.e. temp location)",build_loc.Data());
3318  return kFALSE;
3319  }
3320  ::Warning("ACLiC","Output will be written to %s",
3321  emergency_loc.Data());
3322  return CompileMacro(expFileName, opt, library_specified, emergency_loc, dirmode);
3323  }
3324 
3325  if (withInfo) {
3326  Info("ACLiC","creating shared library %s",library.Data());
3327  }
3328 
3329  R__WriteDependencyFile(build_loc, depfilename, filename_fullpath, library, libname, extension, version_var_prefix, includes, defines, incPath);
3330 
3331  // ======= Select the dictionary name
3332  TString dict = libname + "_ACLiC_dict";
3333 
3334  // the file name end up in the file produced
3335  // by rootcling as a variable name so all character need to be valid!
3336  static const int maxforbidden = 27;
3337  static const char *forbidden_chars[maxforbidden] =
3338  { "+","-","*","/","&","%","|","^",">","<",
3339  "=","~",".","(",")","[","]","!",",","$",
3340  " ",":","'","#","@","\\","\"" };
3341  for( int ic = 0; ic < maxforbidden; ic++ ) {
3342  dict.ReplaceAll( forbidden_chars[ic],"_" );
3343  }
3344  if ( dict.Last('.')!=dict.Length()-1 ) dict.Append(".");
3345  AssignAndDelete( dict, ConcatFileName( build_loc, dict ) );
3346  TString dicth = dict;
3347  TString dictObj = dict;
3348  dict += "cxx"; //no need to keep the extension of the original file, any extension will do
3349  dicth += "h";
3350  dictObj += fObjExt;
3351 
3352  // ======= Generate a linkdef file
3353 
3354  TString linkdef;
3355  AssignAndDelete( linkdef, ConcatFileName( build_loc, libname ) );
3356  linkdef += "_ACLiC_linkdef.h";
3357  std::ofstream linkdefFile( linkdef, std::ios::out );
3358  linkdefFile << "// File Automatically generated by the ROOT Script Compiler "
3359  << std::endl;
3360  linkdefFile << std::endl;
3361  linkdefFile << "#ifdef __CINT__" << std::endl;
3362  linkdefFile << std::endl;
3363  linkdefFile << "#pragma link C++ nestedclasses;" << std::endl;
3364  linkdefFile << "#pragma link C++ nestedtypedefs;" << std::endl;
3365  linkdefFile << std::endl;
3366 
3367  // We want to look for a header file that has the same name as the macro
3368 
3369  const char * extensions[] = { ".h", ".hh", ".hpp", ".hxx", ".hPP", ".hXX" };
3370 
3371  int i;
3372  for (i = 0; i < 6; i++ ) {
3373  char * name;
3374  TString extra_linkdef = BaseName( libname_noext );
3375  extra_linkdef.Append(GetLinkdefSuffix());
3376  extra_linkdef.Append(extensions[i]);
3377  name = Which(incPath,extra_linkdef);
3378  if (name) {
3379  if (verboseLevel>4 && withInfo) {
3380  Info("ACLiC","including extra linkdef file: %s",name);
3381  }
3382  linkdefFile << "#include \"" << name << "\"" << std::endl;
3383  delete [] name;
3384  }
3385  }
3386 
3387  if (verboseLevel>5 && withInfo) {
3388  Info("ACLiC","looking for header in: %s",incPath.Data());
3389  }
3390  for (i = 0; i < 6; i++ ) {
3391  char * name;
3392  TString lookup = BaseName( libname_noext );
3393  lookup.Append(extensions[i]);
3394  name = Which(incPath,lookup);
3395  if (name) {
3396  linkdefFile << "#pragma link C++ defined_in "<<name<<";"<< std::endl;
3397  delete [] name;
3398  }
3399  }
3400  linkdefFile << "#pragma link C++ defined_in \""<<filename_fullpath << "\";" << std::endl;
3401  linkdefFile << std::endl;
3402  linkdefFile << "#endif" << std::endl;
3403  linkdefFile.close();
3404 
3405  // ======= Generate the list of rootmap files to be looked at
3406 
3407  TString mapfile;
3408  AssignAndDelete( mapfile, ConcatFileName( build_loc, libname ) );
3409  mapfile += "_ACLiC_map";
3410  TString mapfilein = mapfile + ".in";
3411  TString mapfileout = mapfile + ".out";
3412 
3413  Bool_t needLoadMap = kFALSE;
3414  if (gInterpreter->GetSharedLibDeps(libname) !=0 ) {
3415  gInterpreter->UnloadLibraryMap(libname);
3416  needLoadMap = kTRUE;
3417  }
3418 
3419  std::ofstream mapfileStream( mapfilein, std::ios::out );
3420  {
3421  TString name = ".rootmap";
3422  TString sname = "system.rootmap";
3423  TString file;
3424  AssignAndDelete(file, ConcatFileName(TROOT::GetEtcDir(), sname) );
3425  if (gSystem->AccessPathName(file)) {
3426  // for backward compatibility check also $ROOTSYS/system<name> if
3427  // $ROOTSYS/etc/system<name> does not exist
3428  AssignAndDelete(file, ConcatFileName(TROOT::GetRootSys(), sname));
3429  if (gSystem->AccessPathName(file)) {
3430  // for backward compatibility check also $ROOTSYS/<name> if
3431  // $ROOTSYS/system<name> does not exist
3432  AssignAndDelete(file, ConcatFileName(TROOT::GetRootSys(), name));
3433  }
3434  }
3435  mapfileStream << file << std::endl;
3436  AssignAndDelete(file, ConcatFileName(gSystem->HomeDirectory(), name) );
3437  mapfileStream << file << std::endl;
3438  mapfileStream << name << std::endl;
3439  if (gInterpreter->GetRootMapFiles()) {
3440  for (i = 0; i < gInterpreter->GetRootMapFiles()->GetEntriesFast(); i++) {
3441  mapfileStream << ((TNamed*)gInterpreter->GetRootMapFiles()->At(i))->GetTitle() << std::endl;
3442  }
3443  }
3444  }
3445  mapfileStream.close();
3446 
3447  // ======= Generate the rootcling command line
3448  TString rcling = "rootcling";
3449  PrependPathName(TROOT::GetBinDir(), rcling);
3450  rcling += " -v0 \"--lib-list-prefix=";
3451  rcling += mapfile;
3452  rcling += "\" -f \"";
3453  rcling.Append(dict).Append("\" -c -p ");
3454  if (produceRootmap) {
3455  rcling += " -rml " + libname + " -rmf \"" + libmapfilename + "\" ";
3456  }
3457  rcling.Append(GetIncludePath()).Append(" -D__ACLIC__ ");
3458  if (produceRootmap) {
3459  rcling.Append("-DR__ACLIC_ROOTMAP ");
3460  }
3461  if (gEnv) {
3462  TString fromConfig = gEnv->GetValue("ACLiC.IncludePaths","");
3463  rcling.Append(fromConfig).Append(" \"");
3464  }
3465  rcling.Append(filename_fullpath).Append("\" \"").Append(linkdef).Append("\"");;
3466 
3467  // ======= Run rootcling
3468  if (withInfo) {
3469  if (verboseLevel>3) {
3470  ::Info("ACLiC","creating the dictionary files");
3471  if (verboseLevel>4) ::Info("ACLiC", "%s", rcling.Data());
3472  }
3473  }
3474 
3475  Int_t dictResult = gSystem->Exec(rcling);
3476  if (dictResult) {
3477  if (dictResult==139) ::Error("ACLiC","Dictionary generation failed with a core dump!");
3478  else ::Error("ACLiC","Dictionary generation failed!");
3479  }
3480 
3481  Bool_t result = !dictResult;
3482  TString depLibraries;
3483 
3484  // ======= Load the library the script might depend on
3485  if (result) {
3486  TString linkedlibs = GetLibraries("", "S");
3487  TString libtoload;
3488  TString all_libtoload;
3489  std::ifstream liblist(mapfileout);
3490 
3491  while ( liblist >> libtoload ) {
3492  // Load the needed library except for the library we are currently building!
3493  if (libtoload == "#") {
3494  // The comment terminates the list of libraries.
3495  std::string toskipcomment;
3496  std::getline(liblist,toskipcomment);
3497  break;
3498  }
3499  if (libtoload != library && libtoload != libname && libtoload != libname_ext) {
3500  if (produceRootmap) {
3501  if (loadLib || linkDepLibraries /* For GetLibraries to Work */) {
3502  result = gROOT->LoadClass("", libtoload) >= 0;
3503  if (!result) {
3504  // We failed to load one of the dependency.
3505  break;
3506  }
3507  }
3508  if (!linkedlibs.Contains(libtoload)) {
3509  all_libtoload.Append(" ").Append(libtoload);
3510  depLibraries.Append(" ");
3511  depLibraries.Append(GetLibraries(libtoload,"DSL",kFALSE));
3512  depLibraries = depLibraries.Strip(); // Remove any trailing spaces.
3513  }
3514  } else {
3515  gROOT->LoadClass("", libtoload);
3516  }
3517  }
3518  unsigned char c = liblist.peek();
3519  if (c=='\n' || c=='\r') {
3520  // Consume the character
3521  liblist.get();
3522  break;
3523  }
3524  }
3525 
3526 // depLibraries = all_libtoload;
3527 // depLibraries.ReplaceAll(" lib"," -l");
3528 // depLibraries.ReplaceAll(TString::Format(".%s",fSoExt.Data()),"");
3529  }
3530 
3531  // ======= Calculate the libraries for linking:
3532  TString linkLibraries;
3533  /*
3534  this is intentionally disabled until it can become useful
3535  if (gEnv) {
3536  linkLibraries = gEnv->GetValue("ACLiC.Libraries","");
3537  linkLibraries.Prepend(" ");
3538  }
3539  */
3540  TString linkLibrariesNoQuotes(GetLibraries("","SDL"));
3541  // We need to enclose the single paths in quotes to account for paths with spaces
3542  TString librariesWithQuotes;
3543  TString singleLibrary;
3544  Bool_t collectingSingleLibraryNameTokens = kFALSE;
3545  for (auto tokenObj : *linkLibrariesNoQuotes.Tokenize(" ")) {
3546  singleLibrary = ((TObjString*)tokenObj)->GetString();
3547  if (!AccessPathName(singleLibrary) || singleLibrary[0]=='-') {
3548  if (collectingSingleLibraryNameTokens) {
3549  librariesWithQuotes.Chop();
3550  librariesWithQuotes += "\" \"" + singleLibrary + "\"";
3551  collectingSingleLibraryNameTokens = kFALSE;
3552  } else {
3553  librariesWithQuotes += " \"" + singleLibrary + "\"";
3554  }
3555  } else {
3556  if (collectingSingleLibraryNameTokens) {
3557  librariesWithQuotes += singleLibrary + " ";
3558  } else {
3559  collectingSingleLibraryNameTokens = kTRUE;
3560  librariesWithQuotes += " \"" + singleLibrary + " ";
3561  }
3562  }
3563  }
3564 
3565  linkLibraries.Prepend(librariesWithQuotes);
3566 
3567  // ======= Generate the build command lines
3568  TString cmd = fMakeSharedLib;
3569  // we do not add filename because it is already included via the dictionary(in dicth) !
3570  // dict.Append(" ").Append(filename);
3571  cmd.ReplaceAll("$SourceFiles","-D__ACLIC__ \"$SourceFiles\"");
3572  cmd.ReplaceAll("$SourceFiles",dict);
3573  cmd.ReplaceAll("$ObjectFiles","\"$ObjectFiles\"");
3574  cmd.ReplaceAll("$ObjectFiles",dictObj);
3575  cmd.ReplaceAll("$IncludePath",includes);
3576  cmd.ReplaceAll("$SharedLib","\"$SharedLib\"");
3577  cmd.ReplaceAll("$SharedLib",library);
3578  if (linkDepLibraries) {
3579  if (produceRootmap) {
3580  cmd.ReplaceAll("$DepLibs",depLibraries);
3581  } else {
3582  cmd.ReplaceAll("$DepLibs",linkLibraries);
3583  }
3584  }
3585  cmd.ReplaceAll("$LinkedLibs",linkLibraries);
3586  cmd.ReplaceAll("$LibName",libname);
3587  cmd.ReplaceAll("\"$BuildDir","$BuildDir");
3588  cmd.ReplaceAll("$BuildDir","\"$BuildDir\"");
3589  cmd.ReplaceAll("$BuildDir",build_loc);
3590  if (mode==kDebug) {
3591  cmd.ReplaceAll("$Opt",fFlagsDebug);
3592  } else {
3593  cmd.ReplaceAll("$Opt",fFlagsOpt);
3594  }
3595 #ifdef WIN32
3596  R__FixLink(cmd);
3597 #endif
3598 
3599  TString testcmd = fMakeExe;
3600  TString fakeMain;
3601  AssignAndDelete( fakeMain, ConcatFileName( build_loc, libname ) );
3602  fakeMain += "_ACLiC_main";
3603  fakeMain += extension;
3604  std::ofstream fakeMainFile( fakeMain, std::ios::out );
3605  fakeMainFile << "// File Automatically generated by the ROOT Script Compiler "
3606  << std::endl;
3607  fakeMainFile << "int main(char*argc,char**argvv) {};" << std::endl;
3608  fakeMainFile.close();
3609  // We could append this fake main routine to the compilation line.
3610  // But in this case compiler may output the name of the dictionary file
3611  // and of the fakeMain file while it compiles it. (this would be useless
3612  // confusing output).
3613  // We could also the fake main routine to the end of the dictionary file
3614  // however compilation would fail if a main is already there
3615  // (like stress.cxx)
3616  // dict.Append(" ").Append(fakeMain);
3617  TString exec;
3618  AssignAndDelete( exec, ConcatFileName( build_loc, libname ) );
3619  exec += "_ACLiC_exec";
3620  testcmd.ReplaceAll("$SourceFiles","-D__ACLIC__ \"$SourceFiles\"");
3621  testcmd.ReplaceAll("$SourceFiles",dict);
3622  testcmd.ReplaceAll("$ObjectFiles","\"$ObjectFiles\"");
3623  testcmd.ReplaceAll("$ObjectFiles",dictObj);
3624  testcmd.ReplaceAll("$IncludePath",includes);
3625  testcmd.ReplaceAll("$ExeName",exec);
3626  testcmd.ReplaceAll("$LinkedLibs",linkLibraries);
3627  testcmd.ReplaceAll("$BuildDir",build_loc);
3628  if (mode==kDebug)
3629  testcmd.ReplaceAll("$Opt",fFlagsDebug);
3630  else
3631  testcmd.ReplaceAll("$Opt",fFlagsOpt);
3632 
3633 #ifdef WIN32
3634  R__FixLink(testcmd);
3635 #endif
3636 
3637  // ======= Build the library
3638  if (result) {
3639  if (verboseLevel>3 && withInfo) {
3640  ::Info("ACLiC","compiling the dictionary and script files");
3641  if (verboseLevel>4) ::Info("ACLiC", "%s", cmd.Data());
3642  }
3643  Int_t compilationResult = gSystem->Exec( cmd );
3644  if (compilationResult) {
3645  if (compilationResult==139) ::Error("ACLiC","Compilation failed with a core dump!");
3646  else ::Error("ACLiC","Compilation failed!");
3647  if (produceRootmap) {
3648  gSystem->Unlink(libmapfilename);
3649  }
3650  }
3651  result = !compilationResult;
3652  }
3653 
3654  if ( result ) {
3655 
3656  TNamed *k = new TNamed(library,library);
3657  Long_t lib_time;
3658  gSystem->GetPathInfo( library, 0, (Long_t*)0, 0, &lib_time );
3659  k->SetUniqueID(lib_time);
3660  if (!keep) k->SetBit(kMustCleanup);
3661  fCompiled->Add(k);
3662 
3663  if (needLoadMap) {
3664  gInterpreter->LoadLibraryMap(libmapfilename);
3665  }
3666  if (verboseLevel>3 && withInfo) ::Info("ACLiC","loading the shared library");
3667  if (loadLib) result = !gSystem->Load(library);
3668  else result = kTRUE;
3669 
3670  if ( !result ) {
3671  if (verboseLevel>3 && withInfo) {
3672  ::Info("ACLiC","testing for missing symbols:");
3673  if (verboseLevel>4) ::Info("ACLiC", "%s", testcmd.Data());
3674  }
3675  gSystem->Exec(testcmd);
3676  gSystem->Unlink( exec );
3677  }
3678 
3679  };
3680 
3681  if (verboseLevel<=5 && !internalDebug) {
3682  gSystem->Unlink( dict );
3683  gSystem->Unlink( dicth );
3684  gSystem->Unlink( dictObj );
3685  gSystem->Unlink( linkdef );
3686  gSystem->Unlink( mapfilein );
3687  gSystem->Unlink( mapfileout );
3688  gSystem->Unlink( fakeMain );
3689  gSystem->Unlink( exec );
3690  }
3691  if (verboseLevel>6) {
3692  rcling.Prepend("echo ");
3693  cmd.Prepend("echo \" ").Append(" \" ");
3694  testcmd.Prepend("echo \" ").Append(" \" ");
3695  gSystem->Exec(rcling);
3696  gSystem->Exec( cmd );
3697  gSystem->Exec(testcmd);
3698  }
3699 
3700  return result;
3701 }
3702 
3703 ////////////////////////////////////////////////////////////////////////////////
3704 /// Return the ACLiC properties field. See EAclicProperties for details
3705 /// on the semantic of each bit.
3706 
3708 {
3709  return fAclicProperties;
3710 }
3711 
3712 ////////////////////////////////////////////////////////////////////////////////
3713 /// Return the build architecture.
3714 
3715 const char *TSystem::GetBuildArch() const
3716 {
3717  return fBuildArch;
3718 }
3719 
3720 ////////////////////////////////////////////////////////////////////////////////
3721 /// Return the build compiler
3722 
3723 const char *TSystem::GetBuildCompiler() const
3724 {
3725  return fBuildCompiler;
3726 }
3727 
3728 ////////////////////////////////////////////////////////////////////////////////
3729 /// Return the build compiler version
3730 
3732 {
3733  return fBuildCompilerVersion;
3734 }
3735 
3736 ////////////////////////////////////////////////////////////////////////////////
3737 /// Return the build node name.
3738 
3739 const char *TSystem::GetBuildNode() const
3740 {
3741  return fBuildNode;
3742 }
3743 
3744 ////////////////////////////////////////////////////////////////////////////////
3745 /// Return the path of the build directory.
3746 
3747 const char *TSystem::GetBuildDir() const
3748 {
3749  if (fBuildDir.Length()==0) {
3750  if (!gEnv) return "";
3751  const_cast<TSystem*>(this)->fBuildDir = gEnv->GetValue("ACLiC.BuildDir","");
3752  }
3753  return fBuildDir;
3754 }
3755 
3756 ////////////////////////////////////////////////////////////////////////////////
3757 /// Return the debug flags.
3758 
3759 const char *TSystem::GetFlagsDebug() const
3760 {
3761  return fFlagsDebug;
3762 }
3763 
3764 ////////////////////////////////////////////////////////////////////////////////
3765 /// Return the optimization flags.
3766 
3767 const char *TSystem::GetFlagsOpt() const
3768 {
3769  return fFlagsOpt;
3770 }
3771 
3772 ////////////////////////////////////////////////////////////////////////////////
3773 /// AclicMode indicates whether the library should be built in
3774 /// debug mode or optimized. The values are:
3775 /// - TSystem::kDefault : compile the same as the current ROOT
3776 /// - TSystem::kDebug : compiled in debug mode
3777 /// - TSystem::kOpt : optimized the library
3778 
3780 {
3781  return fAclicMode;
3782 }
3783 
3784 ////////////////////////////////////////////////////////////////////////////////
3785 /// Return the command line use to make a shared library.
3786 /// See TSystem::CompileMacro for more details.
3787 
3788 const char *TSystem::GetMakeSharedLib() const
3789 {
3790  return fMakeSharedLib;
3791 }
3792 
3793 ////////////////////////////////////////////////////////////////////////////////
3794 /// Return the command line use to make an executable.
3795 /// See TSystem::CompileMacro for more details.
3796 
3797 const char *TSystem::GetMakeExe() const
3798 {
3799  return fMakeExe;
3800 }
3801 
3802 ////////////////////////////////////////////////////////////////////////////////
3803 /// Get the list of include path.
3804 
3806 {
3807  fListPaths = fIncludePath;
3808  fListPaths.Append(" ").Append(gInterpreter->GetIncludePath());
3809  return fListPaths;
3810 }
3811 
3812 ////////////////////////////////////////////////////////////////////////////////
3813 /// Return the list of library linked to this executable.
3814 /// See TSystem::CompileMacro for more details.
3815 
3816 const char *TSystem::GetLinkedLibs() const
3817 {
3818  return fLinkedLibs;
3819 }
3820 
3821 ////////////////////////////////////////////////////////////////////////////////
3822 /// Return the linkdef suffix chosen by the user for ACLiC.
3823 /// See TSystem::CompileMacro for more details.
3824 
3825 const char *TSystem::GetLinkdefSuffix() const
3826 {
3827  if (fLinkdefSuffix.Length()==0) {
3828  if (!gEnv) return "_linkdef";
3829  const_cast<TSystem*>(this)->fLinkdefSuffix = gEnv->GetValue("ACLiC.Linkdef","_linkdef");
3830  }
3831  return fLinkdefSuffix;
3832 }
3833 
3834 ////////////////////////////////////////////////////////////////////////////////
3835 /// Get the shared library extension.
3836 
3837 const char *TSystem::GetSoExt() const
3838 {
3839  return fSoExt;
3840 }
3841 
3842 ////////////////////////////////////////////////////////////////////////////////
3843 /// Get the object file extension.
3844 
3845 const char *TSystem::GetObjExt() const
3846 {
3847  return fObjExt;
3848 }
3849 
3850 ////////////////////////////////////////////////////////////////////////////////
3851 /// Set the location where ACLiC will create libraries and use as
3852 /// a scratch area.
3853 ///
3854 /// If isflast is flase, then the libraries are actually stored in
3855 /// sub-directories of 'build_dir' including the full pathname of the
3856 /// script. If the script is location at /full/path/name/macro.C
3857 /// the library will be located at 'build_dir+/full/path/name/macro_C.so'
3858 /// If 'isflat' is true, then no subdirectory is created and the library
3859 /// is created directly in the directory 'build_dir'. Note that in this
3860 /// mode there is a risk than 2 script of the same in different source
3861 /// directory will over-write each other.
3862 
3863 void TSystem::SetBuildDir(const char* build_dir, Bool_t isflat)
3864 {
3865  fBuildDir = build_dir;
3866  if (isflat) fAclicProperties |= (kFlatBuildDir & kBitMask);
3867  else fAclicProperties &= ~(kFlatBuildDir & kBitMask);
3868 }
3869 
3870 ////////////////////////////////////////////////////////////////////////////////
3871 /// FlagsDebug should contain the options to pass to the C++ compiler
3872 /// in order to compile the library in debug mode.
3873 
3874 void TSystem::SetFlagsDebug(const char *flags)
3875 {
3876  fFlagsDebug = flags;
3877 }
3878 
3879 ////////////////////////////////////////////////////////////////////////////////
3880 /// FlagsOpt should contain the options to pass to the C++ compiler
3881 /// in order to compile the library in optimized mode.
3882 
3883 void TSystem::SetFlagsOpt(const char *flags)
3884 {
3885  fFlagsOpt = flags;
3886 }
3887 
3888 ////////////////////////////////////////////////////////////////////////////////
3889 /// AclicMode indicates whether the library should be built in
3890 /// debug mode or optimized. The values are:
3891 /// - TSystem::kDefault : compile the same as the current ROOT
3892 /// - TSystem::kDebug : compiled in debug mode
3893 /// - TSystem::kOpt : optimized the library
3894 
3896 {
3897  fAclicMode = mode;
3898 }
3899 
3900 ////////////////////////////////////////////////////////////////////////////////
3901 /// Directives has the same syntax as the argument of SetMakeSharedLib but is
3902 /// used to create an executable. This creation is used as a means to output
3903 /// a list of unresolved symbols, when loading a shared library has failed.
3904 /// The required variable is $ExeName rather than $SharedLib, e.g.:
3905 /// ~~~ {.cpp}
3906 /// gSystem->SetMakeExe(
3907 /// "g++ -Wall -fPIC $IncludePath $SourceFiles
3908 /// -o $ExeName $LinkedLibs -L/usr/X11R6/lib -lX11 -lm -ldl -rdynamic");
3909 /// ~~~
3910 
3911 void TSystem::SetMakeExe(const char *directives)
3912 {
3913  fMakeExe = directives;
3914  // NOTE: add verification that the directives has the required variables
3915 }
3916 
3917 ////////////////////////////////////////////////////////////////////////////////
3918 /// Directives should contain the description on how to compile and link a
3919 /// shared lib. This description can be any valid shell command, including
3920 /// the use of ';' to separate several instructions. However, shell specific
3921 /// construct should be avoided. In particular this description can contain
3922 /// environment variables, like $ROOTSYS (or %ROOTSYS% on windows).
3923 /// ~~~ {.cpp}
3924 /// Five special variables will be expanded before execution:
3925 /// Variable name Expands to
3926 /// ------------- ----------
3927 /// $SourceFiles Name of source files to be compiled
3928 /// $SharedLib Name of the shared library being created
3929 /// $LibName Name of shared library without extension
3930 /// $BuildDir Directory where the files will be created
3931 /// $IncludePath value of fIncludePath
3932 /// $LinkedLibs value of fLinkedLibs
3933 /// $DepLibs libraries on which this library depends on
3934 /// $ObjectFiles Name of source files to be compiler with
3935 /// their extension changed to .o or .obj
3936 /// $Opt location of the optimization/debug options
3937 /// set fFlagsDebug and fFlagsOpt
3938 /// ~~~
3939 /// e.g.:
3940 /// ~~~ {.cpp}
3941 /// gSystem->SetMakeSharedLib(
3942 /// "KCC -n32 --strict $IncludePath -K0 \$Opt $SourceFile
3943 /// --no_exceptions --signed_chars --display_error_number
3944 /// --diag_suppress 68 -o $SharedLib");
3945 ///
3946 /// gSystem->setMakeSharedLib(
3947 /// "Cxx $IncludePath -c $SourceFile;
3948 /// ld -L/usr/lib/cmplrs/cxx -rpath /usr/lib/cmplrs/cxx -expect_unresolved
3949 /// \$Opt -shared /usr/lib/cmplrs/cc/crt0.o /usr/lib/cmplrs/cxx/_main.o
3950 /// -o $SharedLib $ObjectFile -lcxxstd -lcxx -lexc -lots -lc"
3951 ///
3952 /// gSystem->SetMakeSharedLib(
3953 /// "$HOME/mygcc/bin/g++ \$Opt -Wall -fPIC $IncludePath $SourceFile
3954 /// -shared -o $SharedLib");
3955 ///
3956 /// gSystem->SetMakeSharedLib(
3957 /// "cl -DWIN32 -D_WIN32 -D_MT -D_DLL -MD /O2 /G5 /MD -DWIN32
3958 /// -D_WINDOWS $IncludePath $SourceFile
3959 /// /link -PDB:NONE /NODEFAULTLIB /INCREMENTAL:NO /RELEASE /NOLOGO
3960 /// $LinkedLibs -entry:_DllMainCRTStartup@12 -dll /out:$SharedLib")
3961 /// ~~~
3962 
3963 void TSystem::SetMakeSharedLib(const char *directives)
3964 {
3965  fMakeSharedLib = directives;
3966  // NOTE: add verification that the directives has the required variables
3967 }
3968 
3969 ////////////////////////////////////////////////////////////////////////////////
3970 /// Add includePath to the already set include path.
3971 
3972 void TSystem::AddIncludePath(const char *includePath)
3973 {
3974  if (includePath) {
3975  fIncludePath += " ";
3976  fIncludePath += includePath;
3977  }
3978 }
3979 
3980 ////////////////////////////////////////////////////////////////////////////////
3981 /// Add linkedLib to already set linked libs.
3982 
3983 void TSystem::AddLinkedLibs(const char *linkedLib)
3984 {
3985  if (linkedLib) {
3986  fLinkedLibs += " ";
3987  fLinkedLibs += linkedLib;
3988  }
3989 }
3990 
3991 ////////////////////////////////////////////////////////////////////////////////
3992 /// IncludePath should contain the list of compiler flags to indicate where
3993 /// to find user defined header files. It is used to expand $IncludePath in
3994 /// the directives given to SetMakeSharedLib() and SetMakeExe(), e.g.:
3995 /// ~~~ {.cpp}
3996 /// gSystem->SetInclude("-I$ROOTSYS/include -Imydirectory/include");
3997 /// ~~~
3998 /// the default value of IncludePath on Unix is:
3999 /// ~~~ {.cpp}
4000 /// "-I$ROOTSYS/include "
4001 /// ~~~
4002 /// and on Windows:
4003 /// ~~~ {.cpp}
4004 /// "/I%ROOTSYS%/include "
4005 /// ~~~
4006 
4007 void TSystem::SetIncludePath(const char *includePath)
4008 {
4009  fIncludePath = includePath;
4010 }
4011 
4012 ////////////////////////////////////////////////////////////////////////////////
4013 /// LinkedLibs should contain the library directory and list of libraries
4014 /// needed to recreate the current executable. It is used to expand $LinkedLibs
4015 /// in the directives given to SetMakeSharedLib() and SetMakeExe()
4016 /// The default value on Unix is: `root-config --glibs`
4017 
4018 void TSystem::SetLinkedLibs(const char *linkedLibs)
4019 {
4020  fLinkedLibs = linkedLibs;
4021 }
4022 
4023 ////////////////////////////////////////////////////////////////////////////////
4024 /// The 'suffix' will be appended to the name of a script loaded by ACLiC
4025 /// and used to locate any eventual additional linkdef information that
4026 /// ACLiC should used to produce the dictionary.
4027 ///
4028 /// So by default, when doing .L MyScript.cxx, ACLiC will look
4029 /// for a file name MyScript_linkdef and having one of the .h (.hpp,
4030 /// etc.) extensions. If such a file exist, it will be added to
4031 /// the end of the linkdef file used to created the ACLiC dictionary.
4032 /// This effectively enable the full customization of the creation
4033 /// of the dictionary. It should be noted that the file is intended
4034 /// as a linkdef `fragment`, so usually you would not list the
4035 /// typical:
4036 /// ~~~ {.cpp}
4037 /// #pragma link off ....
4038 /// ~~~
4039 
4040 void TSystem::SetLinkdefSuffix(const char *suffix)
4041 {
4042  fLinkdefSuffix = suffix;
4043 }
4044 
4045 
4046 ////////////////////////////////////////////////////////////////////////////////
4047 /// Set shared library extension, should be either .so, .sl, .a, .dll, etc.
4048 
4049 void TSystem::SetSoExt(const char *SoExt)
4050 {
4051  fSoExt = SoExt;
4052 }
4053 
4054 ////////////////////////////////////////////////////////////////////////////////
4055 /// Set object files extension, should be either .o, .obj, etc.
4056 
4057 void TSystem::SetObjExt(const char *ObjExt)
4058 {
4059  fObjExt = ObjExt;
4060 }
4061 
4062 ////////////////////////////////////////////////////////////////////////////////
4063 /// This method split a filename of the form:
4064 /// ~~~ {.cpp}
4065 /// [path/]macro.C[+|++[k|f|g|O|c|s|d|v|-]][(args)].
4066 /// ~~~
4067 /// It stores the ACliC mode [+|++[options]] in 'mode',
4068 /// the arguments (including parenthesis) in arg
4069 /// and the I/O indirection in io
4070 
4071 TString TSystem::SplitAclicMode(const char* filename, TString &aclicMode,
4072  TString &arguments, TString &io) const
4073 {
4074  char *fname = Strip(filename);
4075 
4076  char *arg = strchr(fname, '(');
4077  // special case for $(HOME)/aap.C(10)
4078  while (arg && *arg && (arg > fname && *(arg-1) == '$') && *(arg+1))
4079  arg = strchr(arg+1, '(');
4080  if (arg && arg > fname) {
4081  *arg = 0;
4082  char *t = arg-1;
4083  while (*t == ' ') {
4084  *t = 0; t--;
4085  }
4086  arg++;
4087  }
4088 
4089  // strip off I/O redirect tokens from filename
4090  {
4091  char *s2 = 0;
4092  char *s3;
4093  s2 = strstr(fname, ">>");
4094  if (!s2) s2 = strstr(fname, "2>");
4095  if (!s2) s2 = strchr(fname, '>');
4096  s3 = strchr(fname, '<');
4097  if (s2 && s3) s2 = s2<s3 ? s2 : s3;
4098  if (s3 && !s2) s2 = s3;
4099  if (s2==fname) {
4100  io = fname;
4101  aclicMode = "";
4102  arguments = "";
4103  delete []fname;
4104  return "";
4105  } else if (s2) {
4106  s2--;
4107  while (s2 && *s2 == ' ') s2--;
4108  s2++;
4109  io = s2; // ssave = *s2;
4110  *s2 = 0;
4111  } else
4112  io = "";
4113  }
4114 
4115  // remove the possible ACLiC + or ++ and g or O etc
4116  aclicMode.Clear();
4117  int len = strlen(fname);
4118  TString mode;
4119  while (len > 1) {
4120  if (strchr("kfgOcsdv-", fname[len - 1])) {
4121  mode += fname[len - 1];
4122  --len;
4123  } else {
4124  break;
4125  }
4126  }
4127  Bool_t compile = len && fname[len - 1] == '+';
4128  Bool_t remove = compile && len > 1 && fname[len - 2] == '+';
4129  if (compile) {
4130  if (mode.Length()) {
4131  fname[len] = 0;
4132  }
4133  if (remove) {
4134  fname[strlen(fname)-2] = 0;
4135  aclicMode = "++";
4136  } else {
4137  fname[strlen(fname)-1] = 0;
4138  aclicMode = "+";
4139  }
4140  if (mode.Length())
4141  aclicMode += mode;
4142  }
4143 
4144  TString resFilename = fname;
4145  arguments = "(";
4146  if (arg) arguments += arg;
4147  else arguments = "";
4148 
4149  delete []fname;
4150  return resFilename;
4151 }
4152 
4153 ////////////////////////////////////////////////////////////////////////////////
4154 /// Remove the shared libs produced by the CompileMacro() function.
4155 
4157 {
4158  TIter next(fCompiled);
4159  TNamed *lib;
4160  while ((lib = (TNamed*)next())) {
4161  if (lib->TestBit(kMustCleanup)) Unlink(lib->GetTitle());
4162  }
4163 }
4164 
4165 ////////////////////////////////////////////////////////////////////////////////
4166 /// Register version of plugin library.
4167 
4169 {
4170  if (versionCode != TROOT::RootVersionCode() && gLibraryVersion)
4171  gLibraryVersion[gLibraryVersionIdx] = versionCode;
4172 }
virtual const char * BaseName(const char *pathname)
Base name of a file name. Base name of /user/root is root.
Definition: TSystem.cxx:931
virtual void SysError(const char *method, const char *msgfmt,...) const
Issue system error message.
Definition: TObject.cxx:887
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:1272
virtual void Add(TObject *obj)
virtual UInt_t GetUniqueID() const
Return the unique object id.
Definition: TObject.cxx:382
double read(const std::string &file_name)
reading
virtual Bool_t IsAbsoluteFileName(const char *dir)
Return true if dir is an absolute pathname.
Definition: TSystem.cxx:948
virtual int GetPid()
Get process id.
Definition: TSystem.cxx:714
An array of TObjects.
Definition: TObjArray.h:37
virtual int GetCpuInfo(CpuInfo_t *info, Int_t sampleTime=1000) const
Returns cpu load average and load info into the CpuInfo_t structure.
Definition: TSystem.cxx:2445
virtual Bool_t ProcessEvents()
Process pending events (GUI, timers, sockets).
Definition: TSystem.cxx:423
virtual void Syslog(ELogLevel level, const char *mess)
Send mess to syslog daemon.
Definition: TSystem.cxx:1655
virtual const char * GetFlagsOpt() const
Return the optimization flags.
Definition: TSystem.cxx:3767
int GetErrno()
return errno
virtual void Info(const char *method, const char *msgfmt,...) const
Issue info message.
Definition: TObject.cxx:847
virtual const char * GetBuildCompilerVersion() const
Return the build compiler version.
Definition: TSystem.cxx:3731
virtual Bool_t IsPathLocal(const char *path)
Returns TRUE if the url in &#39;path&#39; points to the local file system.
Definition: TSystem.cxx:1281
const char * GetHostAddress() const
Returns the IP address string "%d.%d.%d.%d".
Bool_t ProcessEvents()
Process events if timer did time out.
Definition: TSystem.cxx:84
long long Long64_t
Definition: RtypesCore.h:69
Int_t fReadOffSet
Definition: TSystem.h:210
virtual const char * WorkingDirectory()
Return working directory.
Definition: TSystem.cxx:868
virtual void StackTrace()
Print a stack trace.
Definition: TSystem.cxx:739
EAclicMode
Definition: TSystem.h:251
void Reset()
Reset the timer.
Definition: TTimer.cxx:157
virtual void SetFlagsDebug(const char *)
FlagsDebug should contain the options to pass to the C++ compiler in order to compile the library in ...
Definition: TSystem.cxx:3874
virtual void NotifyApplicationCreated()
Hook to tell TSystem that the TApplication object has been created.
Definition: TSystem.cxx:318
TLine * line
Collectable string class.
Definition: TObjString.h:28
virtual const char * GetLinkedLibs() const
Return the list of library linked to this executable.
Definition: TSystem.cxx:3816
const char Option_t
Definition: RtypesCore.h:62
const char * GetHostName() const
Definition: TInetAddress.h:71
virtual int Link(const char *from, const char *to)
Create a link from file1 to file2.
Definition: TSystem.cxx:1335
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:4071
virtual void SetFlagsOpt(const char *)
FlagsOpt should contain the options to pass to the C++ compiler in order to compile the library in op...
Definition: TSystem.cxx:3883
virtual const char * GetLinkedLibraries()
Get list of shared libraries loaded at the start of the executable.
Definition: TSystem.cxx:2061
void RemoveOnExit(TObject *obj)
Objects that should be deleted on exit of the OS interface.
Definition: TSystem.cxx:299
virtual Int_t SetFPEMask(Int_t mask=kDefaultMask)
Set which conditions trigger a floating point exception.
Definition: TSystem.cxx:649
const Ssiz_t kNPOS
Definition: RtypesCore.h:115
This class represents a WWW compatible URL.
Definition: TUrl.h:35
TString & ReplaceAll(const TString &s1, const TString &s2)
Definition: TString.h:640
virtual const char * GetBuildNode() const
Return the build node name.
Definition: TSystem.cxx:3739
int GetPathInfo(const char *path, Long_t *id, Long_t *size, Long_t *flags, Long_t *modtime)
Get info about a file: id, size, flags, modification time.
Definition: TSystem.cxx:1370
Bool_t TestBit(UInt_t f) const
Definition: TObject.h:159
const char * GetProtocol() const
Definition: TUrl.h:67
static Int_t RootVersionCode()
Return ROOT version code as defined in RVersion.h.
Definition: TROOT.cxx:2683
TH1 * h
Definition: legend2.C:5
virtual TString GetFromPipe(const char *command)
Execute command and return output in TString.
Definition: TSystem.cxx:687
This class represents an Internet Protocol (IP) address.
Definition: TInetAddress.h:36
virtual int MakeDirectory(const char *name)
Make a directory.
Definition: TSystem.cxx:824
virtual void AddSignalHandler(TSignalHandler *sh)
Add a signal handler to list of system signal handlers.
Definition: TSystem.cxx:539
virtual const char * HomeDirectory(const char *userName=0)
Return the user&#39;s home directory.
Definition: TSystem.cxx:884
virtual void CloseConnection(int sock, Bool_t force=kFALSE)
Close socket connection.
Definition: TSystem.cxx:2366
Regular expression class.
Definition: TRegexp.h:31
This class implements a mutex interface.
Definition: TVirtualMutex.h:32
virtual Bool_t ChangeDirectory(const char *path)
Change directory.
Definition: TSystem.cxx:859
TVersionCheck(int versionCode)
Register version of plugin library.
Definition: TSystem.cxx:4168
#define gROOT
Definition: TROOT.h:375
Ssiz_t Index(const char *pat, Ssiz_t i=0, ECaseCompare cmp=kExact) const
Definition: TString.h:587
virtual UserGroup_t * GetGroupInfo(Int_t gid)
Returns all group info in the UserGroup_t structure.
Definition: TSystem.cxx:1594
virtual int GetFsInfo(const char *path, Long_t *id, Long_t *bsize, Long_t *blocks, Long_t *bfree)
Get info about a file system: fs type, block size, number of blocks, number of free blocks...
Definition: TSystem.cxx:1444
virtual void SetMakeExe(const char *directives)
Directives has the same syntax as the argument of SetMakeSharedLib but is used to create an executabl...
Definition: TSystem.cxx:3911
Int_t LoadPlugin()
Load the plugin library for this handler.
virtual void Remove()
Remove std::exception handler from system handler list.
virtual int Load(const char *module, const char *entry="", Bool_t system=kFALSE)
Load a shared library.
Definition: TSystem.cxx:1825
virtual void AddStdExceptionHandler(TStdExceptionHandler *eh)
Add an exception handler to list of system exception handlers.
Definition: TSystem.cxx:618
Basic string class.
Definition: TString.h:129
virtual void ResetSignal(ESignals sig, Bool_t reset=kTRUE)
If reset is true reset the signal handler for the specified signal to the default handler...
Definition: TSystem.cxx:583
virtual int GetMemInfo(MemInfo_t *info) const
Returns ram and swap memory usage info into the MemInfo_t structure.
Definition: TSystem.cxx:2455
static void R__AddPath(TString &target, const TString &path)
Definition: TSystem.cxx:2532
int Int_t
Definition: RtypesCore.h:41
virtual const char * DirName(const char *pathname)
Return the directory name in pathname.
Definition: TSystem.cxx:1003
bool Bool_t
Definition: RtypesCore.h:59
virtual TTimer * RemoveTimer(TTimer *t)
Remove timer from list of system timers.
Definition: TSystem.cxx:488
TArc * a
Definition: textangle.C:12
#define ENDTRY
Definition: TException.h:69
static const TString & GetRootSys()
Get the rootsys directory in the installation. Static utility function.
Definition: TROOT.cxx:2707
virtual const char * GetSoExt() const
Get the shared library extension.
Definition: TSystem.cxx:3837
#define gInterpreter
Definition: TInterpreter.h:499
virtual char * Which(const char *search, const char *file, EAccessMode mode=kFileExists)
Find location of file in a search path.
Definition: TSystem.cxx:1518
Long_t fMtime
Definition: TSystem.h:132
virtual void SetMakeSharedLib(const char *directives)
Directives should contain the description on how to compile and link a shared lib.
Definition: TSystem.cxx:3963
virtual int AnnounceUdpService(int port, int backlog)
Announce UDP service.
Definition: TSystem.cxx:2330
virtual FILE * OpenPipe(const char *command, const char *mode)
Open a pipe.
Definition: TSystem.cxx:669
virtual const char * GetFlagsDebug() const
Return the debug flags.
Definition: TSystem.cxx:3759
TString & Prepend(const char *cs)
Definition: TString.h:609
R__EXTERN TApplication * gApplication
Definition: TApplication.h:165
TObject * At(Int_t idx) const
Definition: TObjArray.h:165
virtual void ResetSignals()
Reset signals handlers to previous behaviour.
Definition: TSystem.cxx:591
virtual void IgnoreInterrupt(Bool_t ignore=kTRUE)
If ignore is true ignore the interrupt signal, else restore previous behaviour.
Definition: TSystem.cxx:609
Basic time type with millisecond precision.
Definition: TTime.h:27
static bool R__MatchFilename(const char *left, const char *right)
Figure out if left and right points to the same object in the file system.
Definition: TSystem.cxx:1785
Long64_t fSize
Definition: TSystem.h:131
virtual TInetAddress GetPeerName(int sock)
Get Internet Protocol (IP) address of remote host and port #.
Definition: TSystem.cxx:2276
static const TString & GetIncludeDir()
Get the include directory in the installation. Static utility function.
Definition: TROOT.cxx:2770
virtual int SendRaw(int sock, const void *buffer, int length, int flag)
Send exactly length bytes from buffer.
Definition: TSystem.cxx:2385
virtual TFileHandler * RemoveFileHandler(TFileHandler *fh)
Remove a file handler from the list of file handlers.
Definition: TSystem.cxx:571
Bool_t R_ISREG(Int_t mode)
Definition: TSystem.h:119
virtual char * GetServiceByPort(int port)
Get name of internet service.
Definition: TSystem.cxx:2303
virtual int mkdir(const char *name, Bool_t recursive=kFALSE)
Make a file system directory.
Definition: TSystem.cxx:903
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
Definition: TObject.cxx:687
TVirtualMutex * gSystemMutex
Definition: TSystem.cxx:102
virtual const char * FindFile(const char *search, TString &file, EAccessMode mode=kFileExists)
Find location of file in a search path.
Definition: TSystem.cxx:1508
virtual const char * UnixPathName(const char *unixpathname)
Convert from a Unix pathname to a local pathname.
Definition: TSystem.cxx:1043
TString & Replace(Ssiz_t pos, Ssiz_t n, const char *s)
Definition: TString.h:630
static Int_t GetErrno()
Static function returning system error number.
Definition: TSystem.cxx:267
Int_t fMode
Definition: TSystem.h:128
Bool_t IsInterruptingSyscalls() const
Definition: TTimer.h:82
virtual int Rename(const char *from, const char *to)
Rename a file.
Definition: TSystem.cxx:1326
virtual const char * GetLinkdefSuffix() const
Return the linkdef suffix chosen by the user for ACLiC.
Definition: TSystem.cxx:3825
const char * GetHost() const
Definition: TUrl.h:70
virtual const char * GetDirEntry(void *dirp)
Get a directory entry. Returns 0 if no more entries.
Definition: TSystem.cxx:850
TTime GetAbsTime() const
Definition: TTimer.h:78
#define SafeDelete(p)
Definition: RConfig.h:499
virtual int Unlink(const char *name)
Unlink, i.e. remove, a file.
Definition: TSystem.cxx:1353
virtual std::string GetHomeDirectory(const char *userName=0) const
Return the user&#39;s home directory.
Definition: TSystem.cxx:892
Double_t x[n]
Definition: legend1.C:17
static TString Format(const char *fmt,...)
Static method which formats a string using a printf style format descriptor and return a TString...
Definition: TString.cxx:2345
virtual int GetSysInfo(SysInfo_t *info) const
Returns static system info, like OS type, CPU type, number of CPUs RAM size, etc into the SysInfo_t s...
Definition: TSystem.cxx:2434
virtual FILE * TempFileName(TString &base, const char *dir=0)
Create a secure temporary file by appending a unique 6 letter string to base.
Definition: TSystem.cxx:1469
virtual void Sleep(UInt_t milliSec)
Sleep milliSec milli seconds.
Definition: TSystem.cxx:444
TText * tt
Definition: textangle.C:16
The TNamed class is the base class for all named ROOT classes.
Definition: TNamed.h:29
Bool_t fTimeout
Definition: TTimer.h:56
TObject * Next()
Return next object in collection.
virtual const char * GetDynamicPath()
Return the dynamic path (used to find shared libraries).
Definition: TSystem.cxx:1764
void Clear()
Clear string without changing its capacity.
Definition: TString.cxx:1150
virtual int CompileMacro(const char *filename, Option_t *opt="", const char *library_name="", const char *build_dir="", UInt_t dirmode=0)
This method compiles and loads a shared library containing the code from the file "filename"...
Definition: TSystem.cxx:2811
virtual const char * Getenv(const char *env)
Get environment variable.
Definition: TSystem.cxx:1634
virtual void ListLibraries(const char *regexp="")
List all loaded shared libraries.
Definition: TSystem.cxx:2006
virtual const char * GetMakeExe() const
Return the command line use to make an executable.
Definition: TSystem.cxx:3797
virtual void SetDisplay()
Set DISPLAY environment variable based on utmp entry. Only for UNIX.
Definition: TSystem.cxx:238
TString & Append(const char *cs)
Definition: TString.h:497
virtual const char * PrependPathName(const char *dir, TString &name)
Concatenate a directory and a file name.
Definition: TSystem.cxx:1061
Bool_t EndsWith(const char *pat, ECaseCompare cmp=kExact) const
Return true if string ends with the specified string.
Definition: TString.cxx:2231
virtual EAclicMode GetAclicMode() const
AclicMode indicates whether the library should be built in debug mode or optimized.
Definition: TSystem.cxx:3779
virtual void ExitLoop()
Exit from event loop.
Definition: TSystem.cxx:399
virtual UserGroup_t * GetUserInfo(Int_t uid)
Returns all user info in the UserGroup_t structure.
Definition: TSystem.cxx:1570
virtual int RecvRaw(int sock, void *buffer, int length, int flag)
Receive exactly length bytes into buffer.
Definition: TSystem.cxx:2375
Ssiz_t First(char c) const
Find first occurrence of a character c.
Definition: TString.cxx:477
virtual ~TSystem()
Delete the OS interface.
Definition: TSystem.cxx:145
virtual void Unload(const char *module)
Unload a shared library.
Definition: TSystem.cxx:1985
virtual const char * TempDirectory() const
Return a user configured or systemwide directory to create temporary files in.
Definition: TSystem.cxx:1454
static Int_t gLibraryVersionMax
Definition: TSystem.cxx:65
virtual Bool_t ConsistentWith(const char *path, void *dirptr=0)
Check consistency of this helper with the one required by &#39;path&#39; or &#39;dirptr&#39;.
Definition: TSystem.cxx:801
virtual TInetAddress GetHostByName(const char *server)
Get Internet Protocol (IP) address of host.
Definition: TSystem.cxx:2267
void Error(const char *location, const char *msgfmt,...)
ELogLevel
Definition: TSystem.h:56
virtual void Closelog()
Close connection to system log daemon.
Definition: TSystem.cxx:1663
virtual const char * GetBuildCompiler() const
Return the build compiler.
Definition: TSystem.cxx:3723
virtual void SetUniqueID(UInt_t uid)
Set the unique object id.
Definition: TObject.cxx:698
A doubly linked list.
Definition: TList.h:43
TString & GetLastErrorString()
Return the thread local storage for the custom last error message.
Definition: TSystem.cxx:2043
const char * GetUser() const
Definition: TUrl.h:68
static Int_t * gLibraryVersion
Definition: TSystem.cxx:63
virtual EStatus Handle(std::exception &exc)=0
void Remove()
Definition: TTimer.h:85
virtual void AddDynamicPath(const char *pathname)
Add a new directory to the dynamic path.
Definition: TSystem.cxx:1756
ESignals
TString fUser
Definition: TSystem.h:142
virtual const char * GetBuildArch() const
Return the build architecture.
Definition: TSystem.cxx:3715
virtual TTime Now()
Get current time in milliseconds since 0:00 Jan 1 1995.
Definition: TSystem.cxx:470
virtual TObject * FindObject(const char *name) const
Must be redefined in derived classes.
Definition: TObject.cxx:328
virtual void Setenv(const char *name, const char *value)
Set environment variable.
Definition: TSystem.cxx:1618
virtual TStdExceptionHandler * RemoveStdExceptionHandler(TStdExceptionHandler *eh)
Remove an exception handler from list of exception handlers.
Definition: TSystem.cxx:628
void ResetErrno()
reset errno
static void R__WriteDependencyFile(const TString &build_loc, const TString &depfilename, const TString &filename, const TString &library, const TString &libname, const TString &extension, const char *version_var_prefix, const TString &includes, const TString &defines, const TString &incPath)
Definition: TSystem.cxx:2546
TRandom2 r(17)
virtual Bool_t Init()
Initialize the OS interface.
Definition: TSystem.cxx:189
SVector< double, 2 > v
Definition: Dict.h:5
if object ctor succeeded but object should not be used
Definition: TObject.h:65
virtual const char * GetLibraries(const char *regexp="", const char *option="", Bool_t isRegexp=kTRUE)
Return a space separated list of loaded shared libraries.
Definition: TSystem.cxx:2079
const char * gProgName
Definition: TSystem.cxx:57
Long_t ExecPlugin(int nargs, const T &... params)
virtual Int_t GetValue(const char *name, Int_t dflt)
Returns the integer value for a resource.
Definition: TEnv.cxx:482
virtual int AcceptConnection(int sock)
Accept a connection.
Definition: TSystem.cxx:2357
Bool_t Gets(FILE *fp, Bool_t chop=kTRUE)
Read one line from the stream, including the , or until EOF.
Definition: Stringio.cxx:198
void AssignAndDelete(TString &target, char *tobedeleted)
Definition: TSystem.cxx:2473
Bool_t BeginsWith(const char *s, ECaseCompare cmp=kExact) const
Definition: TString.h:563
virtual void SetDynamicPath(const char *pathname)
Set the dynamic path to a new value.
Definition: TSystem.cxx:1775
virtual int AnnounceTcpService(int port, Bool_t reuse, int backlog, int tcpwindowsize=-1)
Announce TCP/IP service.
Definition: TSystem.cxx:2321
virtual const char * GetBuildDir() const
Return the path of the build directory.
Definition: TSystem.cxx:3747
virtual Long_t NextTimeOut(Bool_t mode)
Time when next timer of mode (synchronous=kTRUE or asynchronous=kFALSE) will time-out (in ms)...
Definition: TSystem.cxx:501
Bool_t IsSync() const
Definition: TTimer.h:80
static Int_t ConvertVersionCode2Int(Int_t code)
Convert version code to an integer, i.e. 331527 -> 51507.
Definition: TROOT.cxx:2664
unsigned int UInt_t
Definition: RtypesCore.h:42
Int_t GetEntriesFast() const
Definition: TObjArray.h:64
bool verbose
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition: TObject.cxx:873
char * Form(const char *fmt,...)
Ssiz_t Length() const
Definition: TString.h:388
virtual int Umask(Int_t mask)
Set the process file creation mode mask.
Definition: TSystem.cxx:1487
virtual void SetBuildDir(const char *build_dir, Bool_t isflat=kFALSE)
Set the location where ACLiC will create libraries and use as a scratch area.
Definition: TSystem.cxx:3863
TSubString Strip(EStripType s=kTrailing, char c=' ') const
Return a substring of self stripped at beginning and/or end.
Definition: TString.cxx:1080
virtual Int_t GetAclicProperties() const
Return the ACLiC properties field.
Definition: TSystem.cxx:3707
virtual int SendBuf(int sock, const void *buffer, int length)
Send a buffer headed by a length indicator.
Definition: TSystem.cxx:2403
const char * gProgPath
Definition: TSystem.cxx:58
TLine * l
Definition: textangle.C:4
Handles synchronous and a-synchronous timer events.
Definition: TTimer.h:51
virtual void ListSymbols(const char *module, const char *re="")
List symbols in a shared library.
Definition: TSystem.cxx:1997
TFileHandler * gXDisplay
Definition: TSystem.cxx:61
const std::string sname
Definition: testIO.cxx:45
virtual Int_t Exec(const char *shellcmd)
Execute a command.
Definition: TSystem.cxx:660
virtual void StopIdleing()
Called when system stops idleing.
virtual int Utime(const char *file, Long_t modtime, Long_t actime)
Set the a files modification and access times.
Definition: TSystem.cxx:1497
char * Strip(const char *str, char c=' ')
Strip leading and trailing c (blanks by default) from a string.
Definition: TString.cxx:2488
virtual void Abort(int code=0)
Abort the application.
Definition: TSystem.cxx:731
virtual void InnerLoop()
Inner event loop.
Definition: TSystem.cxx:407
virtual const char * GetMakeSharedLib() const
Return the command line use to make a shared library.
Definition: TSystem.cxx:3788
virtual void SetSoExt(const char *soExt)
Set shared library extension, should be either .so, .sl, .a, .dll, etc.
Definition: TSystem.cxx:4049
virtual void Unsetenv(const char *name)
Unset environment variable.
Definition: TSystem.cxx:1626
if object destructor must call RecursiveRemove()
Definition: TObject.h:59
virtual void FreeDirectory(void *dirp)
Free a directory.
Definition: TSystem.cxx:842
virtual int ClosePipe(FILE *pipe)
Close the pipe.
Definition: TSystem.cxx:678
virtual void Run()
System event loop.
Definition: TSystem.cxx:350
#define Printf
Definition: TGeoToOCC.h:18
char * StrDup(const char *str)
Duplicate the string str.
Definition: TString.cxx:2524
#define R__LOCKGUARD2(mutex)
virtual int OpenConnection(const char *server, int port, int tcpwindowsize=-1, const char *protocol="tcp")
Open a connection to another host.
Definition: TSystem.cxx:2312
const Bool_t kFALSE
Definition: RtypesCore.h:92
virtual int SetSockOpt(int sock, int kind, int val)
Set socket option.
Definition: TSystem.cxx:2412
const char * extension
Definition: civetweb.c:5005
virtual Int_t Select(TList *active, Long_t timeout)
Select on active file descriptors (called by TMonitor).
Definition: TSystem.cxx:452
virtual const char * FindDynamicLibrary(TString &lib, Bool_t quiet=kFALSE)
Find a dynamic library using the system search paths.
Definition: TSystem.cxx:1967
virtual Int_t RedirectOutput(const char *name, const char *mode="a", RedirectHandle_t *h=0)
Redirect standard output (stdout, stderr) to the specified file.
Definition: TSystem.cxx:1684
TString & Remove(Ssiz_t pos)
Definition: TString.h:621
long Long_t
Definition: RtypesCore.h:50
int Ssiz_t
Definition: RtypesCore.h:63
virtual int Chmod(const char *file, UInt_t mode)
Set the file permission bits. Returns -1 in case or error, 0 otherwise.
Definition: TSystem.cxx:1478
virtual TSignalHandler * RemoveSignalHandler(TSignalHandler *sh)
Remove a signal handler from list of signal handlers.
Definition: TSystem.cxx:549
virtual void StartIdleing()
Called when system starts idleing.
TObjArray * Tokenize(const TString &delim) const
This function is used to isolate sequential tokens in a TString.
Definition: TString.cxx:2251
virtual Int_t GetEffectiveUid()
Returns the effective user id.
Definition: TSystem.cxx:1541
virtual const char * GetIncludePath()
Get the list of include path.
Definition: TSystem.cxx:3805
#define ClassImp(name)
Definition: Rtypes.h:336
double f(double x)
virtual Func_t DynFindSymbol(const char *module, const char *entry)
Find specific entry point in specified library.
Definition: TSystem.cxx:1977
virtual const char * HostName()
Return the system&#39;s host name.
Definition: TSystem.cxx:310
virtual int Symlink(const char *from, const char *to)
Create a symbolic link from file1 to file2.
Definition: TSystem.cxx:1344
Ssiz_t Index(const TString &str, Ssiz_t *len, Ssiz_t start=0) const
Find the first occurrence of the regexp in string and return the position, or -1 if there is no match...
Definition: TRegexp.cxx:209
Ssiz_t Last(char c) const
Find last occurrence of a character c.
Definition: TString.cxx:875
char * DynamicPathName(const char *lib, Bool_t quiet=kFALSE)
Find a dynamic library called lib using the system search paths.
Definition: TSystem.cxx:1953
ELogFacility
Definition: TSystem.h:67
virtual void Remove()
Remove signal handler from system signal handler list.
R__EXTERN TEnv * gEnv
Definition: TEnv.h:170
virtual const char * ExpandFileName(const char *fname)
Expand a pathname getting rid of special shell characters like ~.
Definition: TSystem.cxx:1078
static const TString & GetEtcDir()
Get the sysconfig directory in the installation. Static utility function.
Definition: TROOT.cxx:2791
virtual void SetProgname(const char *name)
Set the application name (from command line, argv[0]) and copy it in gProgName.
Definition: TSystem.cxx:230
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition: TString.h:572
TSystem * gSystem
Definition: TSystem.cxx:60
you should not use this method at all Int_t Int_t Double_t Double_t Double_t e
Definition: TRolke.cxx:630
virtual Int_t GetGid(const char *group=0)
Returns the group&#39;s id. If group = 0, returns current user&#39;s group.
Definition: TSystem.cxx:1550
void Beep(Int_t freq=-1, Int_t duration=-1, Bool_t setDefault=kFALSE)
Beep for duration milliseconds with a tone of frequency freq.
Definition: TSystem.cxx:331
virtual void DispatchOneEvent(Bool_t pendingOnly=kFALSE)
Dispatch a single event.
Definition: TSystem.cxx:436
virtual void CleanCompiledMacros()
Remove the shared libs produced by the CompileMacro() function.
Definition: TSystem.cxx:4156
virtual TInetAddress GetSockName(int sock)
Get Internet Protocol (IP) address of host and port #.
Definition: TSystem.cxx:2285
virtual Int_t GetUid(const char *user=0)
Returns the user&#39;s id. If user = 0, returns current user&#39;s id.
Definition: TSystem.cxx:1531
EAccessMode
Definition: TSystem.h:44
virtual void Remove()
Remove file event handler from system file handler list.
virtual void AddLinkedLibs(const char *linkedLib)
Add linkedLib to already set linked libs.
Definition: TSystem.cxx:3983
Bool_t IsNull() const
Definition: TString.h:385
virtual void SetAclicMode(EAclicMode mode)
AclicMode indicates whether the library should be built in debug mode or optimized.
Definition: TSystem.cxx:3895
Mother of all ROOT objects.
Definition: TObject.h:37
virtual void SetObjExt(const char *objExt)
Set object files extension, should be either .o, .obj, etc.
Definition: TSystem.cxx:4057
virtual Bool_t IsFileInIncludePath(const char *name, char **fullpath=0)
Return true if &#39;name&#39; is a file that can be found in the ROOT include path or the current directory...
Definition: TSystem.cxx:963
virtual const char * GetTitle() const
Returns title of object.
Definition: TObject.cxx:408
virtual int RecvBuf(int sock, void *buffer, int length)
Receive a buffer headed by a length indicator.
Definition: TSystem.cxx:2394
virtual void Openlog(const char *name, Int_t options, ELogFacility facility)
Open connection to system log daemon.
Definition: TSystem.cxx:1646
Bool_t R_ISDIR(Int_t mode)
Definition: TSystem.h:116
virtual int GetServiceByName(const char *service)
Get port # of internet service.
Definition: TSystem.cxx:2294
virtual int AnnounceUnixService(int port, int backlog)
Announce unix domain service.
Definition: TSystem.cxx:2339
static const TString & GetLibDir()
Get the library directory in the installation. Static utility function.
Definition: TROOT.cxx:2749
virtual void AddTimer(TTimer *t)
Add timer to list of system timers.
Definition: TSystem.cxx:478
virtual void ShowOutput(RedirectHandle_t *h)
Display the content associated with the redirection described by the opaque handle &#39;h&#39;...
Definition: TSystem.cxx:1694
Definition: file.py:1
virtual void SetLinkedLibs(const char *linkedLibs)
LinkedLibs should contain the library directory and list of libraries needed to recreate the current ...
Definition: TSystem.cxx:4018
virtual Int_t GetEffectiveGid()
Returns the effective group id.
Definition: TSystem.cxx:1560
virtual void Exit(int code, Bool_t mode=kTRUE)
Exit the application.
Definition: TSystem.cxx:723
#define ROOT_RELEASE
Definition: RVersion.h:17
virtual std::string GetWorkingDirectory() const
Return working directory.
Definition: TSystem.cxx:876
virtual int GetProcInfo(ProcInfo_t *info) const
Returns cpu and memory used by this process into the ProcInfo_t structure.
Definition: TSystem.cxx:2465
const Int_t kMaxInt
Definition: RtypesCore.h:103
you should not use this method at all Int_t Int_t Double_t Double_t Double_t Int_t Double_t Double_t Double_t Double_t b
Definition: TRolke.cxx:630
Long_t fIno
Definition: TSystem.h:127
#define snprintf
Definition: civetweb.c:822
virtual int CopyFile(const char *from, const char *to, Bool_t overwrite=kFALSE)
Copy a file.
Definition: TSystem.cxx:1317
virtual void * OpenDirectory(const char *name)
Open a directory. Returns 0 if directory does not exist.
Definition: TSystem.cxx:833
R__EXTERN Int_t gDebug
Definition: Rtypes.h:83
Iterator of ordered collection.
virtual void AddIncludePath(const char *includePath)
Add includePath to the already set include path.
Definition: TSystem.cxx:3972
TSystem * FindHelper(const char *path, void *dirptr=0)
Create helper TSystem to handle file and directory operations that might be special for remote file a...
Definition: TSystem.cxx:751
virtual void AddFileHandler(TFileHandler *fh)
Add a file handler to the list of system file handlers.
Definition: TSystem.cxx:561
static void ResetErrno()
Static function resetting system error number.
Definition: TSystem.cxx:283
static const TString & GetBinDir()
Get the binary directory in the installation. Static utility function.
Definition: TROOT.cxx:2728
double result[121]
virtual Bool_t ExpandPathName(TString &path)
Expand a pathname getting rid of special shell characters like ~.
Definition: TSystem.cxx:1250
void SetErrorStr(const char *errstr)
Set the system error string.
Definition: TSystem.cxx:248
Long_t fDev
Definition: TSystem.h:126
virtual const char * GetName() const
Returns name of object.
Definition: TObject.cxx:364
virtual int GetSockOpt(int sock, int kind, int *val)
Get socket option.
Definition: TSystem.cxx:2421
const char * gRootDir
Definition: TSystem.cxx:56
Abstract base class defining a generic interface to the underlying Operating System.
Definition: TSystem.h:248
Ordered collection.
virtual void SetLinkdefSuffix(const char *suffix)
The &#39;suffix&#39; will be appended to the name of a script loaded by ACLiC and used to locate any eventual...
Definition: TSystem.cxx:4040
virtual Int_t GetFPEMask()
Return the bitmap of conditions that trigger a floating point exception.
Definition: TSystem.cxx:639
#define RETRY
Definition: TException.h:49
static Int_t gLibraryVersionIdx
Definition: TSystem.cxx:64
const Bool_t kTRUE
Definition: RtypesCore.h:91
void AbstractMethod(const char *method) const
Use this method to implement an "abstract" method that you don&#39;t want to leave purely abstract...
Definition: TObject.cxx:915
virtual char * ConcatFileName(const char *dir, const char *name)
Concatenate a directory and a file name. User must delete returned string.
Definition: TSystem.cxx:1051
Bool_t IsAsync() const
Definition: TTimer.h:81
const Int_t n
Definition: legend1.C:16
TString fFile
Definition: TSystem.h:205
virtual const char * GetObjExt() const
Get the object file extension.
Definition: TSystem.cxx:3845
virtual const char * GetError()
Return system error string.
Definition: TSystem.cxx:257
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition: TObject.cxx:859
static Int_t * ReAllocInt(Int_t *vp, size_t size, size_t oldsize)
Reallocate (i.e.
Definition: TStorage.cxx:295
virtual void SetIncludePath(const char *includePath)
IncludePath should contain the list of compiler flags to indicate where to find user defined header f...
Definition: TSystem.cxx:4007
virtual const char * GetTitle() const
Returns title of object.
Definition: TNamed.h:48
TString & Chop()
Definition: TString.h:627
const char * Data() const
Definition: TString.h:347
virtual void IgnoreSignal(ESignals sig, Bool_t ignore=kTRUE)
If ignore is true ignore the specified signal, else restore previous behaviour.
Definition: TSystem.cxx:600