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