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