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