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