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