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