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