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