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