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