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