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