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