ROOT  6.06/09
Reference Guide
TUnixSystem.cxx
Go to the documentation of this file.
1 // @(#)root/unix:$Id: 887c618d89c4ed436e4034fc133f468fecad651b $
2 // Author: Fons Rademakers 15/09/95
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2000, 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 //////////////////////////////////////////////////////////////////////////
13 // //
14 // TUnixSystem //
15 // //
16 // Class providing an interface to the UNIX Operating System. //
17 // //
18 //////////////////////////////////////////////////////////////////////////
19 
20 #include "RConfigure.h"
21 #include "RConfig.h"
22 #include "TUnixSystem.h"
23 #include "TROOT.h"
24 #include "TError.h"
25 #include "TOrdCollection.h"
26 #include "TRegexp.h"
27 #include "TPRegexp.h"
28 #include "TException.h"
29 #include "Demangle.h"
30 #include "TEnv.h"
31 #include "TSocket.h"
32 #include "Getline.h"
33 #include "TInterpreter.h"
34 #include "TApplication.h"
35 #include "TObjString.h"
36 #include "Riostream.h"
37 #include "TVirtualMutex.h"
38 #include "TObjArray.h"
39 #include <map>
40 #include <algorithm>
41 #include <atomic>
42 
43 //#define G__OLDEXPAND
44 
45 #include <unistd.h>
46 #include <stdlib.h>
47 #include <sys/types.h>
48 #if defined(R__SUN) || defined(R__AIX) || \
49  defined(R__LINUX) || defined(R__SOLARIS) || \
50  defined(R__FBSD) || defined(R__OBSD) || \
51  defined(R__MACOSX) || defined(R__HURD)
52 #define HAS_DIRENT
53 #endif
54 #ifdef HAS_DIRENT
55 # include <dirent.h>
56 #else
57 # include <sys/dir.h>
58 #endif
59 #if defined(ULTRIX) || defined(R__SUN)
60 # include <sgtty.h>
61 #endif
62 #if defined(R__AIX) || defined(R__LINUX) || \
63  defined(R__FBSD) || defined(R__OBSD) || \
64  defined(R__LYNXOS) || defined(R__MACOSX) || defined(R__HURD)
65 # include <sys/ioctl.h>
66 #endif
67 #if defined(R__AIX) || defined(R__SOLARIS)
68 # include <sys/select.h>
69 #endif
70 #if defined(R__LINUX) || defined(R__HURD)
71 # ifndef SIGSYS
72 # define SIGSYS SIGUNUSED // SIGSYS does not exist in linux ??
73 # endif
74 #endif
75 #if defined(R__MACOSX)
76 # include <mach-o/dyld.h>
77 # include <sys/mount.h>
78  extern "C" int statfs(const char *file, struct statfs *buffer);
79 #elif defined(R__LINUX) || defined(R__HURD)
80 # include <sys/vfs.h>
81 #elif defined(R__FBSD) || defined(R__OBSD)
82 # include <sys/param.h>
83 # include <sys/mount.h>
84 #else
85 # include <sys/statfs.h>
86 #endif
87 
88 #include <utime.h>
89 #include <syslog.h>
90 #include <sys/stat.h>
91 #include <setjmp.h>
92 #include <signal.h>
93 #include <sys/param.h>
94 #include <pwd.h>
95 #include <grp.h>
96 #include <errno.h>
97 #include <sys/resource.h>
98 #include <sys/wait.h>
99 #include <time.h>
100 #include <sys/time.h>
101 #include <sys/file.h>
102 #include <sys/socket.h>
103 #include <netinet/in.h>
104 #include <netinet/tcp.h>
105 #if defined(R__AIX)
106 # define _XOPEN_EXTENDED_SOURCE
107 # include <arpa/inet.h>
108 # undef _XOPEN_EXTENDED_SOURCE
109 # if !defined(_AIX41) && !defined(_AIX43)
110  // AIX 3.2 doesn't have it
111 # define HASNOT_INETATON
112 # endif
113 #else
114 # include <arpa/inet.h>
115 #endif
116 #include <sys/un.h>
117 #include <netdb.h>
118 #include <fcntl.h>
119 #if defined(R__SOLARIS)
120 # include <sys/systeminfo.h>
121 # include <sys/filio.h>
122 # include <sys/sockio.h>
123 # define HASNOT_INETATON
124 # ifndef INADDR_NONE
125 # define INADDR_NONE (UInt_t)-1
126 # endif
127 #endif
128 
129 #if defined(R__SOLARIS)
130 # define HAVE_UTMPX_H
131 # define UTMP_NO_ADDR
132 #endif
133 
134 #if defined(MAC_OS_X_VERSION_10_5)
135 # define HAVE_UTMPX_H
136 # define UTMP_NO_ADDR
137 # ifndef ut_user
138 # define ut_user ut_name
139 # endif
140 #endif
141 
142 #if defined(R__FBSD)
143 # include <sys/param.h>
144 # if __FreeBSD_version >= 900007
145 # define HAVE_UTMPX_H
146 # ifndef ut_user
147 # define ut_user ut_name
148 # endif
149 # endif
150 #endif
151 
152 #if defined(R__AIX) || defined(R__FBSD) || \
153  defined(R__OBSD) || defined(R__LYNXOS) || \
154  (defined(R__MACOSX) && !defined(MAC_OS_X_VERSION_10_5))
155 # define UTMP_NO_ADDR
156 #endif
157 
158 #if (defined(R__AIX) && !defined(_AIX43)) || \
159  (defined(R__SUNGCC3) && !defined(__arch64__))
160 # define USE_SIZE_T
161 #elif defined(R__GLIBC) || defined(R__FBSD) || \
162  (defined(R__SUNGCC3) && defined(__arch64__)) || \
163  defined(R__OBSD) || defined(MAC_OS_X_VERSION_10_4) || \
164  (defined(R__AIX) && defined(_AIX43)) || \
165  (defined(R__SOLARIS) && defined(_SOCKLEN_T))
166 # define USE_SOCKLEN_T
167 #endif
168 
169 #if defined(R__LYNXOS)
170 extern "C" {
171  extern int putenv(const char *);
172  extern int inet_aton(const char *, struct in_addr *);
173 };
174 #endif
175 
176 #ifdef HAVE_UTMPX_H
177 #include <utmpx.h>
178 #define STRUCT_UTMP struct utmpx
179 #else
180 #include <utmp.h>
181 #define STRUCT_UTMP struct utmp
182 #endif
183 #if !defined(UTMP_FILE) && defined(_PATH_UTMP) // 4.4BSD
184 #define UTMP_FILE _PATH_UTMP
185 #endif
186 #if defined(UTMPX_FILE) // Solaris, SysVr4
187 #undef UTMP_FILE
188 #define UTMP_FILE UTMPX_FILE
189 #endif
190 #ifndef UTMP_FILE
191 #define UTMP_FILE "/etc/utmp"
192 #endif
193 
194 // stack trace code
195 #if (defined(R__LINUX) || defined(R__HURD)) && !defined(R__WINGCC)
196 # if __GLIBC__ == 2 && __GLIBC_MINOR__ >= 1
197 # define HAVE_BACKTRACE_SYMBOLS_FD
198 # endif
199 # define HAVE_DLADDR
200 #endif
201 #if defined(R__MACOSX)
202 # if defined(MAC_OS_X_VERSION_10_5)
203 # define HAVE_BACKTRACE_SYMBOLS_FD
204 # define HAVE_DLADDR
205 # else
206 # define USE_GDB_STACK_TRACE
207 # endif
208 #endif
209 
210 #ifdef HAVE_BACKTRACE_SYMBOLS_FD
211 # include <execinfo.h>
212 #endif
213 #ifdef HAVE_DLADDR
214 # ifndef __USE_GNU
215 # define __USE_GNU
216 # endif
217 # include <dlfcn.h>
218 #endif
219 
220 #ifdef HAVE_BACKTRACE_SYMBOLS_FD
221  // The maximum stack trace depth for systems where we request the
222  // stack depth separately (currently glibc-based systems).
223  static const int kMAX_BACKTRACE_DEPTH = 128;
224 #endif
225 
226 // FPE handling includes
227 #if (defined(R__LINUX) && !defined(R__WINGCC))
228 #include <fpu_control.h>
229 #include <fenv.h>
230 #include <sys/prctl.h> // for prctl() function used in StackTrace()
231 #endif
232 
233 #if defined(R__MACOSX) && defined(__SSE2__)
234 #include <xmmintrin.h>
235 #endif
236 
237 #if defined(R__MACOSX) && !defined(__SSE2__) && !defined(__xlC__) && \
238  !defined(__i386__) && !defined(__x86_64__) && !defined(__arm__) && \
239  !defined(__arm64__)
240 #include <fenv.h>
241 #include <signal.h>
242 #include <ucontext.h>
243 #include <stdlib.h>
244 #include <stdio.h>
245 #include <mach/thread_status.h>
246 
247 #define fegetenvd(x) asm volatile("mffs %0" : "=f" (x));
248 #define fesetenvd(x) asm volatile("mtfsf 255,%0" : : "f" (x));
249 
250 enum {
251  FE_ENABLE_INEXACT = 0x00000008,
252  FE_ENABLE_DIVBYZERO = 0x00000010,
253  FE_ENABLE_UNDERFLOW = 0x00000020,
254  FE_ENABLE_OVERFLOW = 0x00000040,
255  FE_ENABLE_INVALID = 0x00000080,
256  FE_ENABLE_ALL_EXCEPT = 0x000000F8
257 };
258 #endif
259 
260 #if defined(R__MACOSX) && !defined(__SSE2__) && \
261  (defined(__i386__) || defined(__x86_64__) || defined(__arm__) || defined(__arm64__))
262 #include <fenv.h>
263 #endif
264 // End FPE handling includes
265 
266 
267 struct TUtmpContent {
268  STRUCT_UTMP *fUtmpContents;
269  UInt_t fEntries; // Number of entries in utmp file.
270 
271  TUtmpContent() : fUtmpContents(0), fEntries(0) {}
272  ~TUtmpContent() { free(fUtmpContents); }
273 
274  STRUCT_UTMP *SearchUtmpEntry(const char *tty)
275  {
276  // Look for utmp entry which is connected to terminal tty.
277 
278  STRUCT_UTMP *ue = fUtmpContents;
279 
280  UInt_t n = fEntries;
281  while (n--) {
282  if (ue->ut_name[0] && !strncmp(tty, ue->ut_line, sizeof(ue->ut_line)))
283  return ue;
284  ue++;
285  }
286  return 0;
287  }
288 
289  int ReadUtmpFile()
290  {
291  // Read utmp file. Returns number of entries in utmp file.
292 
293  FILE *utmp;
294  struct stat file_stats;
295  size_t n_read, size;
296 
297  fEntries = 0;
298 
300 
301  utmp = fopen(UTMP_FILE, "r");
302  if (!utmp)
303  return 0;
304 
305  if (fstat(fileno(utmp), &file_stats) == -1) {
306  fclose(utmp);
307  return 0;
308  }
309  size = file_stats.st_size;
310  if (size <= 0) {
311  fclose(utmp);
312  return 0;
313  }
314 
315  fUtmpContents = (STRUCT_UTMP *) malloc(size);
316  if (!fUtmpContents) {
317  fclose(utmp);
318  return 0;
319  }
320 
321  n_read = fread(fUtmpContents, 1, size, utmp);
322  if (!ferror(utmp)) {
323  if (fclose(utmp) != EOF && n_read == size) {
324  fEntries = size / sizeof(STRUCT_UTMP);
325  return fEntries;
326  }
327  } else
328  fclose(utmp);
329 
330  free(fUtmpContents);
331  fUtmpContents = 0;
332  return 0;
333  }
334 
335 };
336 
337 const char *kServerPath = "/tmp";
338 const char *kProtocolName = "tcp";
339 
340 //------------------- Unix TFdSet ----------------------------------------------
341 #ifndef HOWMANY
342 # define HOWMANY(x, y) (((x)+((y)-1))/(y))
343 #endif
344 
345 const Int_t kNFDBITS = (sizeof(Long_t) * 8); // 8 bits per byte
346 #ifdef FD_SETSIZE
347 const Int_t kFDSETSIZE = FD_SETSIZE; // Linux = 1024 file descriptors
348 #else
349 const Int_t kFDSETSIZE = 256; // upto 256 file descriptors
350 #endif
351 
352 
353 class TFdSet {
354 private:
355  ULong_t fds_bits[HOWMANY(kFDSETSIZE, kNFDBITS)];
356 public:
357  TFdSet() { memset(fds_bits, 0, sizeof(fds_bits)); }
358  TFdSet(const TFdSet &org) { memcpy(fds_bits, org.fds_bits, sizeof(org.fds_bits)); }
359  TFdSet &operator=(const TFdSet &rhs) { if (this != &rhs) { memcpy(fds_bits, rhs.fds_bits, sizeof(rhs.fds_bits));} return *this; }
360  void Zero() { memset(fds_bits, 0, sizeof(fds_bits)); }
361  void Set(Int_t n)
362  {
363  if (n >= 0 && n < kFDSETSIZE) {
364  fds_bits[n/kNFDBITS] |= (1UL << (n % kNFDBITS));
365  } else {
366  ::Fatal("TFdSet::Set","fd (%d) out of range [0..%d]", n, kFDSETSIZE-1);
367  }
368  }
369  void Clr(Int_t n)
370  {
371  if (n >= 0 && n < kFDSETSIZE) {
372  fds_bits[n/kNFDBITS] &= ~(1UL << (n % kNFDBITS));
373  } else {
374  ::Fatal("TFdSet::Clr","fd (%d) out of range [0..%d]", n, kFDSETSIZE-1);
375  }
376  }
377  Int_t IsSet(Int_t n)
378  {
379  if (n >= 0 && n < kFDSETSIZE) {
380  return (fds_bits[n/kNFDBITS] & (1UL << (n % kNFDBITS))) != 0;
381  } else {
382  ::Fatal("TFdSet::IsSet","fd (%d) out of range [0..%d]", n, kFDSETSIZE-1);
383  return 0;
384  }
385  }
386  ULong_t *GetBits() { return (ULong_t *)fds_bits; }
387 };
388 
389 ////////////////////////////////////////////////////////////////////////////////
390 /// Unix signal handler.
391 
392 static void SigHandler(ESignals sig)
393 {
394  if (gSystem)
395  ((TUnixSystem*)gSystem)->DispatchSignals(sig);
396 }
397 
398 ////////////////////////////////////////////////////////////////////////////////
399 
400 static const char *GetExePath()
401 {
402  TTHREAD_TLS_DECL(TString,exepath);
403  if (exepath == "") {
404 #if defined(R__MACOSX)
405  exepath = _dyld_get_image_name(0);
406 #elif defined(R__LINUX) || defined(R__SOLARIS) || defined(R__FBSD)
407  char buf[kMAXPATHLEN]; // exe path name
408 
409  // get the name from the link in /proc
410 #if defined(R__LINUX)
411  int ret = readlink("/proc/self/exe", buf, kMAXPATHLEN);
412 #elif defined(R__SOLARIS)
413  int ret = readlink("/proc/self/path/a.out", buf, kMAXPATHLEN);
414 #elif defined(R__FBSD)
415  int ret = readlink("/proc/curproc/file", buf, kMAXPATHLEN);
416 #endif
417  if (ret > 0 && ret < kMAXPATHLEN) {
418  buf[ret] = 0;
419  exepath = buf;
420  }
421 #else
422  if (!gApplication)
423  return exepath;
424  TString p = gApplication->Argv(0);
425  if (p.BeginsWith("/"))
426  exepath = p;
427  else if (p.Contains("/")) {
428  exepath = gSystem->WorkingDirectory();
429  exepath += "/";
430  exepath += p;
431  } else {
432  char *exe = gSystem->Which(gSystem->Getenv("PATH"), p, kExecutePermission);
433  if (exe) {
434  exepath = exe;
435  delete [] exe;
436  }
437  }
438 #endif
439  }
440  return exepath;
441 }
442 
443 #if defined(HAVE_DLADDR) && !defined(R__MACOSX)
444 ////////////////////////////////////////////////////////////////////////////////
445 
446 static void SetRootSys()
447 {
448 #ifndef ROOTPREFIX
449  void *addr = (void *)SetRootSys;
450  Dl_info info;
451  if (dladdr(addr, &info) && info.dli_fname && info.dli_fname[0]) {
452  char respath[kMAXPATHLEN];
453  if (!realpath(info.dli_fname, respath)) {
454  if (!gSystem->Getenv("ROOTSYS"))
455  ::SysError("TUnixSystem::SetRootSys", "error getting realpath of libCore, please set ROOTSYS in the shell");
456  } else {
457  TString rs = gSystem->DirName(respath);
458  gSystem->Setenv("ROOTSYS", gSystem->DirName(rs));
459  }
460  }
461 #else
462  return;
463 #endif
464 }
465 #endif
466 
467 #if defined(R__MACOSX)
468 static TString gLinkedDylibs;
469 
470 ////////////////////////////////////////////////////////////////////////////////
471 
472 static void DylibAdded(const struct mach_header *mh, intptr_t /* vmaddr_slide */)
473 {
474  static int i = 0;
475  static Bool_t gotFirstSo = kFALSE;
476  static TString linkedDylibs;
477 
478  // to copy the local linkedDylibs to the global gLinkedDylibs call this
479  // function with mh==0
480  if (!mh) {
481  gLinkedDylibs = linkedDylibs;
482  return;
483  }
484 
485  TString lib = _dyld_get_image_name(i++);
486 
487  TRegexp sovers = "libCore\\.[0-9]+\\.*[0-9]*\\.so";
488  TRegexp dyvers = "libCore\\.[0-9]+\\.*[0-9]*\\.dylib";
489 
490 #ifndef ROOTPREFIX
491 #if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR
492  // first loaded is the app so set ROOTSYS to app bundle
493  if (i == 1) {
494  char respath[kMAXPATHLEN];
495  if (!realpath(lib, respath)) {
496  if (!gSystem->Getenv("ROOTSYS"))
497  ::SysError("TUnixSystem::DylibAdded", "error getting realpath of %s", gSystem->BaseName(lib));
498  } else {
499  TString rs = gSystem->DirName(respath);
500  gSystem->Setenv("ROOTSYS", rs);
501  }
502  }
503 #else
504  if (lib.EndsWith("libCore.dylib") || lib.EndsWith("libCore.so") ||
505  lib.Index(sovers) != kNPOS || lib.Index(dyvers) != kNPOS) {
506  char respath[kMAXPATHLEN];
507  if (!realpath(lib, respath)) {
508  if (!gSystem->Getenv("ROOTSYS"))
509  ::SysError("TUnixSystem::DylibAdded", "error getting realpath of libCore, please set ROOTSYS in the shell");
510  } else {
511  TString rs = gSystem->DirName(respath);
512  gSystem->Setenv("ROOTSYS", gSystem->DirName(rs));
513  }
514  }
515 #endif
516 #endif
517 
518  // when libSystem.B.dylib is loaded we have finished loading all dylibs
519  // explicitly linked against the executable. Additional dylibs
520  // come when they are explicitly linked against loaded so's, currently
521  // we are not interested in these
522  if (lib.EndsWith("/libSystem.B.dylib"))
523  gotFirstSo = kTRUE;
524 
525  // add all libs loaded before libSystem.B.dylib
526  if (!gotFirstSo && (lib.EndsWith(".dylib") || lib.EndsWith(".so"))) {
527  sovers = "\\.[0-9]+\\.*[0-9]*\\.so";
528  Ssiz_t idx = lib.Index(sovers);
529  if (idx != kNPOS) {
530  lib.Remove(idx);
531  lib += ".so";
532  }
533  dyvers = "\\.[0-9]+\\.*[0-9]*\\.dylib";
534  idx = lib.Index(dyvers);
535  if (idx != kNPOS) {
536  lib.Remove(idx);
537  lib += ".dylib";
538  }
539  if (!gSystem->AccessPathName(lib, kReadPermission)) {
540  if (linkedDylibs.Length())
541  linkedDylibs += " ";
542  linkedDylibs += lib;
543  }
544  }
545 }
546 #endif
547 
549 
550 ////////////////////////////////////////////////////////////////////////////////
551 
552 TUnixSystem::TUnixSystem() : TSystem("Unix", "Unix System")
553 { }
554 
555 ////////////////////////////////////////////////////////////////////////////////
556 /// Reset to original state.
557 
559 {
561 
562  delete fReadmask;
563  delete fWritemask;
564  delete fReadready;
565  delete fWriteready;
566  delete fSignals;
567 }
568 
569 ////////////////////////////////////////////////////////////////////////////////
570 /// Initialize Unix system interface.
571 
573 {
574  if (TSystem::Init())
575  return kTRUE;
576 
577  fReadmask = new TFdSet;
578  fWritemask = new TFdSet;
579  fReadready = new TFdSet;
580  fWriteready = new TFdSet;
581  fSignals = new TFdSet;
582 
583  //--- install default handlers
594 
595 #if defined(R__MACOSX)
596  // trap loading of all dylibs to register dylib name,
597  // sets also ROOTSYS if built without ROOTPREFIX
598  _dyld_register_func_for_add_image(DylibAdded);
599 #elif defined(HAVE_DLADDR)
600  SetRootSys();
601 #endif
602 
603 #ifndef ROOTPREFIX
604  gRootDir = Getenv("ROOTSYS");
605  if (gRootDir == 0)
606  gRootDir= "/usr/local/root";
607 #else
608  gRootDir = ROOTPREFIX;
609 #endif
610 
611  return kFALSE;
612 }
613 
614 //---- Misc --------------------------------------------------------------------
615 
616 ////////////////////////////////////////////////////////////////////////////////
617 /// Set the application name (from command line, argv[0]) and copy it in
618 /// gProgName. Copy the application pathname in gProgPath.
619 /// If name is 0 let the system set the actual executable name and path
620 /// (works on MacOS X and Linux).
621 
622 void TUnixSystem::SetProgname(const char *name)
623 {
624  if (gProgName)
625  delete [] gProgName;
626  if (gProgPath)
627  delete [] gProgPath;
628 
629  if (!name || !*name) {
630  name = GetExePath();
631  gProgName = StrDup(BaseName(name));
632  gProgPath = StrDup(DirName(name));
633  } else {
634  gProgName = StrDup(BaseName(name));
635  char *w = Which(Getenv("PATH"), gProgName);
636  gProgPath = StrDup(DirName(w));
637  delete [] w;
638  }
639 }
640 
641 ////////////////////////////////////////////////////////////////////////////////
642 /// Set DISPLAY environment variable based on utmp entry. Only for UNIX.
643 
645 {
646  if (!Getenv("DISPLAY")) {
647  char *tty = ::ttyname(0); // device user is logged in on
648  if (tty) {
649  tty += 5; // remove "/dev/"
650 
651  TUtmpContent utmp;
652  utmp.ReadUtmpFile();
653 
654  STRUCT_UTMP *utmp_entry = utmp.SearchUtmpEntry(tty);
655  if (utmp_entry) {
656  if (utmp_entry->ut_host[0]) {
657  if (strchr(utmp_entry->ut_host, ':')) {
658  Setenv("DISPLAY", utmp_entry->ut_host);
659  Warning("SetDisplay", "DISPLAY not set, setting it to %s",
660  utmp_entry->ut_host);
661  } else {
662  char disp[64];
663  snprintf(disp, sizeof(disp), "%s:0.0", utmp_entry->ut_host);
664  Setenv("DISPLAY", disp);
665  Warning("SetDisplay", "DISPLAY not set, setting it to %s",
666  disp);
667  }
668  }
669 #ifndef UTMP_NO_ADDR
670  else if (utmp_entry->ut_addr) {
671  struct hostent *he;
672  if ((he = gethostbyaddr((const char*)&utmp_entry->ut_addr,
673  sizeof(utmp_entry->ut_addr), AF_INET))) {
674  char disp[64];
675  snprintf(disp, sizeof(disp), "%s:0.0", he->h_name);
676  Setenv("DISPLAY", disp);
677  Warning("SetDisplay", "DISPLAY not set, setting it to %s",
678  disp);
679  }
680  }
681 #endif
682  }
683  }
684  }
685 }
686 
687 ////////////////////////////////////////////////////////////////////////////////
688 /// Return system error string.
689 
691 {
692  Int_t err = GetErrno();
693  if (err == 0 && GetLastErrorString() != "")
694  return GetLastErrorString();
695 
696 #if defined(R__SOLARIS) || defined (R__LINUX) || defined(R__AIX) || \
697  defined(R__FBSD) || defined(R__OBSD) || defined(R__HURD)
698  return strerror(err);
699 #else
700  if (err < 0 || err >= sys_nerr)
701  return Form("errno out of range %d", err);
702  return sys_errlist[err];
703 #endif
704 }
705 
706 ////////////////////////////////////////////////////////////////////////////////
707 /// Return the system's host name.
708 
710 {
711  if (fHostname == "") {
712  char hn[64];
713 #if defined(R__SOLARIS)
714  sysinfo(SI_HOSTNAME, hn, sizeof(hn));
715 #else
716  gethostname(hn, sizeof(hn));
717 #endif
718  fHostname = hn;
719  }
720  return (const char *)fHostname;
721 }
722 
723 //---- EventLoop ---------------------------------------------------------------
724 
725 ////////////////////////////////////////////////////////////////////////////////
726 /// Add a file handler to the list of system file handlers. Only adds
727 /// the handler if it is not already in the list of file handlers.
728 
730 {
732 
734  if (h) {
735  int fd = h->GetFd();
736  if (h->HasReadInterest()) {
737  fReadmask->Set(fd);
738  fMaxrfd = TMath::Max(fMaxrfd, fd);
739  }
740  if (h->HasWriteInterest()) {
741  fWritemask->Set(fd);
742  fMaxwfd = TMath::Max(fMaxwfd, fd);
743  }
744  }
745 }
746 
747 ////////////////////////////////////////////////////////////////////////////////
748 /// Remove a file handler from the list of file handlers. Returns
749 /// the handler or 0 if the handler was not in the list of file handlers.
750 
752 {
753  if (!h) return 0;
754 
756 
758  if (oh) { // found
759  TFileHandler *th;
761  fMaxrfd = -1;
762  fMaxwfd = -1;
763  fReadmask->Zero();
764  fWritemask->Zero();
765  while ((th = (TFileHandler *) next())) {
766  int fd = th->GetFd();
767  if (th->HasReadInterest()) {
768  fReadmask->Set(fd);
769  fMaxrfd = TMath::Max(fMaxrfd, fd);
770  }
771  if (th->HasWriteInterest()) {
772  fWritemask->Set(fd);
773  fMaxwfd = TMath::Max(fMaxwfd, fd);
774  }
775  }
776  }
777  return oh;
778 }
779 
780 ////////////////////////////////////////////////////////////////////////////////
781 /// Add a signal handler to list of system signal handlers. Only adds
782 /// the handler if it is not already in the list of signal handlers.
783 
785 {
787 
790 }
791 
792 ////////////////////////////////////////////////////////////////////////////////
793 /// Remove a signal handler from list of signal handlers. Returns
794 /// the handler or 0 if the handler was not in the list of signal handlers.
795 
797 {
798  if (!h) return 0;
799 
801 
803 
804  Bool_t last = kTRUE;
805  TSignalHandler *hs;
807 
808  while ((hs = (TSignalHandler*) next())) {
809  if (hs->GetSignal() == h->GetSignal())
810  last = kFALSE;
811  }
812  if (last)
813  ResetSignal(h->GetSignal(), kTRUE);
814 
815  return oh;
816 }
817 
818 ////////////////////////////////////////////////////////////////////////////////
819 /// If reset is true reset the signal handler for the specified signal
820 /// to the default handler, else restore previous behaviour.
821 
823 {
824  if (reset)
825  UnixResetSignal(sig);
826  else
827  UnixSignal(sig, SigHandler);
828 }
829 
830 ////////////////////////////////////////////////////////////////////////////////
831 /// Reset signals handlers to previous behaviour.
832 
834 {
836 }
837 
838 ////////////////////////////////////////////////////////////////////////////////
839 /// If ignore is true ignore the specified signal, else restore previous
840 /// behaviour.
841 
843 {
844  UnixIgnoreSignal(sig, ignore);
845 }
846 
847 ////////////////////////////////////////////////////////////////////////////////
848 /// When the argument is true the SIGALRM signal handler is set so that
849 /// interrupted syscalls will not be restarted by the kernel. This is
850 /// typically used in case one wants to put a timeout on an I/O operation.
851 /// By default interrupted syscalls will always be restarted (for all
852 /// signals). This can be controlled for each a-synchronous TTimer via
853 /// the method TTimer::SetInterruptSyscalls().
854 
856 {
858 }
859 
860 ////////////////////////////////////////////////////////////////////////////////
861 /// Return the bitmap of conditions that trigger a floating point exception.
862 
864 {
865  Int_t mask = 0;
866 
867 #if defined(R__LINUX) && !defined(__powerpc__)
868 #if defined(__GLIBC__) && (__GLIBC__>2 || __GLIBC__==2 && __GLIBC_MINOR__>=1)
869 
870 #if __GLIBC_MINOR__>=3
871 
872  Int_t oldmask = fegetexcept();
873 
874 #else
875  fenv_t oldenv;
876  fegetenv(&oldenv);
877  fesetenv(&oldenv);
878 #if __ia64__
879  Int_t oldmask = ~oldenv;
880 #else
881  Int_t oldmask = ~oldenv.__control_word;
882 #endif
883 #endif
884 
885  if (oldmask & FE_INVALID ) mask |= kInvalid;
886  if (oldmask & FE_DIVBYZERO) mask |= kDivByZero;
887  if (oldmask & FE_OVERFLOW ) mask |= kOverflow;
888  if (oldmask & FE_UNDERFLOW) mask |= kUnderflow;
889 # ifdef FE_INEXACT
890  if (oldmask & FE_INEXACT ) mask |= kInexact;
891 # endif
892 #endif
893 #endif
894 
895 #if defined(R__MACOSX) && defined(__SSE2__)
896  // OS X uses the SSE unit for all FP math by default, not the x87 FP unit
897  Int_t oldmask = ~_MM_GET_EXCEPTION_MASK();
898 
899  if (oldmask & _MM_MASK_INVALID ) mask |= kInvalid;
900  if (oldmask & _MM_MASK_DIV_ZERO ) mask |= kDivByZero;
901  if (oldmask & _MM_MASK_OVERFLOW ) mask |= kOverflow;
902  if (oldmask & _MM_MASK_UNDERFLOW) mask |= kUnderflow;
903  if (oldmask & _MM_MASK_INEXACT ) mask |= kInexact;
904 #endif
905 
906 #if defined(R__MACOSX) && !defined(__SSE2__) && \
907  (defined(__i386__) || defined(__x86_64__) || defined(__arm__) || defined(__arm64__))
908  fenv_t oldenv;
909  fegetenv(&oldenv);
910  fesetenv(&oldenv);
911 #if defined(__arm__)
912  Int_t oldmask = ~oldenv.__fpscr;
913 #elif defined(__arm64__)
914  Int_t oldmask = ~oldenv.__fpcr;
915 #else
916  Int_t oldmask = ~oldenv.__control;
917 #endif
918 
919  if (oldmask & FE_INVALID ) mask |= kInvalid;
920  if (oldmask & FE_DIVBYZERO) mask |= kDivByZero;
921  if (oldmask & FE_OVERFLOW ) mask |= kOverflow;
922  if (oldmask & FE_UNDERFLOW) mask |= kUnderflow;
923  if (oldmask & FE_INEXACT ) mask |= kInexact;
924 #endif
925 
926 #if defined(R__MACOSX) && !defined(__SSE2__) && !defined(__xlC__) && \
927  !defined(__i386__) && !defined(__x86_64__) && !defined(__arm__) && \
928  !defined(__arm64__)
929  Long64_t oldmask;
930  fegetenvd(oldmask);
931 
932  if (oldmask & FE_ENABLE_INVALID ) mask |= kInvalid;
933  if (oldmask & FE_ENABLE_DIVBYZERO) mask |= kDivByZero;
934  if (oldmask & FE_ENABLE_OVERFLOW ) mask |= kOverflow;
935  if (oldmask & FE_ENABLE_UNDERFLOW) mask |= kUnderflow;
936  if (oldmask & FE_ENABLE_INEXACT ) mask |= kInexact;
937 #endif
938 
939  return mask;
940 }
941 
942 ////////////////////////////////////////////////////////////////////////////////
943 /// Set which conditions trigger a floating point exception.
944 /// Return the previous set of conditions.
945 
947 {
948  if (mask) { } // use mask to avoid warning
949 
950  Int_t old = GetFPEMask();
951 
952 #if defined(R__LINUX) && !defined(__powerpc__)
953 #if defined(__GLIBC__) && (__GLIBC__>2 || __GLIBC__==2 && __GLIBC_MINOR__>=1)
954  Int_t newm = 0;
955  if (mask & kInvalid ) newm |= FE_INVALID;
956  if (mask & kDivByZero) newm |= FE_DIVBYZERO;
957  if (mask & kOverflow ) newm |= FE_OVERFLOW;
958  if (mask & kUnderflow) newm |= FE_UNDERFLOW;
959 # ifdef FE_INEXACT
960  if (mask & kInexact ) newm |= FE_INEXACT;
961 # endif
962 
963 #if __GLIBC_MINOR__>=3
964 
965  // clear pending exceptions so feenableexcept does not trigger them
966  feclearexcept(FE_ALL_EXCEPT);
967  fedisableexcept(FE_ALL_EXCEPT);
968  feenableexcept(newm);
969 
970 #else
971 
972  fenv_t cur;
973  fegetenv(&cur);
974 #if defined __ia64__
975  cur &= ~newm;
976 #else
977  cur.__control_word &= ~newm;
978 #endif
979  fesetenv(&cur);
980 
981 #endif
982 #endif
983 #endif
984 
985 #if defined(R__MACOSX) && defined(__SSE2__)
986  // OS X uses the SSE unit for all FP math by default, not the x87 FP unit
987  Int_t newm = 0;
988  if (mask & kInvalid ) newm |= _MM_MASK_INVALID;
989  if (mask & kDivByZero) newm |= _MM_MASK_DIV_ZERO;
990  if (mask & kOverflow ) newm |= _MM_MASK_OVERFLOW;
991  if (mask & kUnderflow) newm |= _MM_MASK_UNDERFLOW;
992  if (mask & kInexact ) newm |= _MM_MASK_INEXACT;
993 
994  _MM_SET_EXCEPTION_MASK(_MM_GET_EXCEPTION_MASK() & ~newm);
995 #endif
996 
997 #if defined(R__MACOSX) && !defined(__SSE2__) && \
998  (defined(__i386__) || defined(__x86_64__) || defined(__arm__) || defined(__arm64__))
999  Int_t newm = 0;
1000  if (mask & kInvalid ) newm |= FE_INVALID;
1001  if (mask & kDivByZero) newm |= FE_DIVBYZERO;
1002  if (mask & kOverflow ) newm |= FE_OVERFLOW;
1003  if (mask & kUnderflow) newm |= FE_UNDERFLOW;
1004  if (mask & kInexact ) newm |= FE_INEXACT;
1005 
1006  fenv_t cur;
1007  fegetenv(&cur);
1008 #if defined(__arm__)
1009  cur.__fpscr &= ~newm;
1010 #elif defined(__arm64__)
1011  cur.__fpcr &= ~newm;
1012 #else
1013  cur.__control &= ~newm;
1014 #endif
1015  fesetenv(&cur);
1016 #endif
1017 
1018 #if defined(R__MACOSX) && !defined(__SSE2__) && !defined(__xlC__) && \
1019  !defined(__i386__) && !defined(__x86_64__) && !defined(__arm__) && \
1020  !defined(__arm64__)
1021  Int_t newm = 0;
1022  if (mask & kInvalid ) newm |= FE_ENABLE_INVALID;
1023  if (mask & kDivByZero) newm |= FE_ENABLE_DIVBYZERO;
1024  if (mask & kOverflow ) newm |= FE_ENABLE_OVERFLOW;
1025  if (mask & kUnderflow) newm |= FE_ENABLE_UNDERFLOW;
1026  if (mask & kInexact ) newm |= FE_ENABLE_INEXACT;
1027 
1028  Long64_t curmask;
1029  fegetenvd(curmask);
1030  curmask = (curmask & ~FE_ENABLE_ALL_EXCEPT) | newm;
1031  fesetenvd(curmask);
1032 #endif
1033 
1034  return old;
1035 }
1036 
1037 ////////////////////////////////////////////////////////////////////////////////
1038 /// Dispatch a single event.
1039 
1041 {
1042  Bool_t pollOnce = pendingOnly;
1043 
1044  while (1) {
1045  // first handle any X11 events
1046  if (gXDisplay && gXDisplay->Notify()) {
1047  if (fReadready->IsSet(gXDisplay->GetFd())) {
1048  fReadready->Clr(gXDisplay->GetFd());
1049  fNfd--;
1050  }
1051  if (!pendingOnly) return;
1052  }
1053 
1054  // check for file descriptors ready for reading/writing
1055  if (fNfd > 0 && fFileHandler && fFileHandler->GetSize() > 0)
1056  if (CheckDescriptors())
1057  if (!pendingOnly) return;
1058  fNfd = 0;
1059  fReadready->Zero();
1060  fWriteready->Zero();
1061 
1062  if (pendingOnly && !pollOnce)
1063  return;
1064 
1065  // check synchronous signals
1066  if (fSigcnt > 0 && fSignalHandler->GetSize() > 0)
1067  if (CheckSignals(kTRUE))
1068  if (!pendingOnly) return;
1069  fSigcnt = 0;
1070  fSignals->Zero();
1071 
1072  // check synchronous timers
1073  Long_t nextto;
1074  if (fTimers && fTimers->GetSize() > 0)
1075  if (DispatchTimers(kTRUE)) {
1076  // prevent timers from blocking file descriptor monitoring
1077  nextto = NextTimeOut(kTRUE);
1078  if (nextto > kItimerResolution || nextto == -1)
1079  return;
1080  }
1081 
1082  // if in pendingOnly mode poll once file descriptor activity
1083  nextto = NextTimeOut(kTRUE);
1084  if (pendingOnly) {
1085  if (fFileHandler && fFileHandler->GetSize() == 0)
1086  return;
1087  nextto = 0;
1088  pollOnce = kFALSE;
1089  }
1090 
1091  // nothing ready, so setup select call
1092  *fReadready = *fReadmask;
1093  *fWriteready = *fWritemask;
1094 
1095  int mxfd = TMath::Max(fMaxrfd, fMaxwfd);
1096  mxfd++;
1097 
1098  // if nothing to select (socket or timer) return
1099  if (mxfd == 0 && nextto == -1)
1100  return;
1101 
1102  fNfd = UnixSelect(mxfd, fReadready, fWriteready, nextto);
1103  if (fNfd < 0 && fNfd != -2) {
1104  int fd, rc;
1105  TFdSet t;
1106  for (fd = 0; fd < mxfd; fd++) {
1107  t.Set(fd);
1108  if (fReadmask->IsSet(fd)) {
1109  rc = UnixSelect(fd+1, &t, 0, 0);
1110  if (rc < 0 && rc != -2) {
1111  SysError("DispatchOneEvent", "select: read error on %d", fd);
1112  fReadmask->Clr(fd);
1113  }
1114  }
1115  if (fWritemask->IsSet(fd)) {
1116  rc = UnixSelect(fd+1, 0, &t, 0);
1117  if (rc < 0 && rc != -2) {
1118  SysError("DispatchOneEvent", "select: write error on %d", fd);
1119  fWritemask->Clr(fd);
1120  }
1121  }
1122  t.Clr(fd);
1123  }
1124  }
1125  }
1126 }
1127 
1128 ////////////////////////////////////////////////////////////////////////////////
1129 /// Sleep milliSec milliseconds.
1130 
1132 {
1133  struct timeval tv;
1134 
1135  tv.tv_sec = milliSec / 1000;
1136  tv.tv_usec = (milliSec % 1000) * 1000;
1137 
1138  select(0, 0, 0, 0, &tv);
1139 }
1140 
1141 ////////////////////////////////////////////////////////////////////////////////
1142 /// Select on file descriptors. The timeout to is in millisec. Returns
1143 /// the number of ready descriptors, or 0 in case of timeout, or < 0 in
1144 /// case of an error, with -2 being EINTR and -3 EBADF. In case of EINTR
1145 /// the errno has been reset and the method can be called again. Returns
1146 /// -4 in case the list did not contain any file handlers or file handlers
1147 /// with file descriptor >= 0.
1148 
1150 {
1151  Int_t rc = -4;
1152 
1153  TFdSet rd, wr;
1154  Int_t mxfd = -1;
1155  TIter next(act);
1156  TFileHandler *h = 0;
1157  while ((h = (TFileHandler *) next())) {
1158  Int_t fd = h->GetFd();
1159  if (fd > -1) {
1160  if (h->HasReadInterest()) {
1161  rd.Set(fd);
1162  mxfd = TMath::Max(mxfd, fd);
1163  }
1164  if (h->HasWriteInterest()) {
1165  wr.Set(fd);
1166  mxfd = TMath::Max(mxfd, fd);
1167  }
1168  h->ResetReadyMask();
1169  }
1170  }
1171  if (mxfd > -1)
1172  rc = UnixSelect(mxfd+1, &rd, &wr, to);
1173 
1174  // Set readiness bits
1175  if (rc > 0) {
1176  next.Reset();
1177  while ((h = (TFileHandler *) next())) {
1178  Int_t fd = h->GetFd();
1179  if (rd.IsSet(fd))
1180  h->SetReadReady();
1181  if (wr.IsSet(fd))
1182  h->SetWriteReady();
1183  }
1184  }
1185 
1186  return rc;
1187 }
1188 
1189 ////////////////////////////////////////////////////////////////////////////////
1190 /// Select on the file descriptor related to file handler h.
1191 /// The timeout to is in millisec. Returns the number of ready descriptors,
1192 /// or 0 in case of timeout, or < 0 in case of an error, with -2 being EINTR
1193 /// and -3 EBADF. In case of EINTR the errno has been reset and the method
1194 /// can be called again. Returns -4 in case the file handler is 0 or does
1195 /// not have a file descriptor >= 0.
1196 
1198 {
1199  Int_t rc = -4;
1200 
1201  TFdSet rd, wr;
1202  Int_t mxfd = -1;
1203  Int_t fd = -1;
1204  if (h) {
1205  fd = h->GetFd();
1206  if (fd > -1) {
1207  if (h->HasReadInterest())
1208  rd.Set(fd);
1209  if (h->HasWriteInterest())
1210  wr.Set(fd);
1211  h->ResetReadyMask();
1212  mxfd = fd;
1213  rc = UnixSelect(mxfd+1, &rd, &wr, to);
1214  }
1215  }
1216 
1217  // Fill output lists, if required
1218  if (rc > 0) {
1219  if (rd.IsSet(fd))
1220  h->SetReadReady();
1221  if (wr.IsSet(fd))
1222  h->SetWriteReady();
1223  }
1224 
1225  return rc;
1226 }
1227 
1228 //---- handling of system events -----------------------------------------------
1229 
1230 ////////////////////////////////////////////////////////////////////////////////
1231 /// Check if some signals were raised and call their Notify() member.
1232 
1234 {
1235  TSignalHandler *sh;
1236  Int_t sigdone = -1;
1237  {
1239 
1240  while ((sh = (TSignalHandler*)it.Next())) {
1241  if (sync == sh->IsSync()) {
1242  ESignals sig = sh->GetSignal();
1243  if ((fSignals->IsSet(sig) && sigdone == -1) || sigdone == sig) {
1244  if (sigdone == -1) {
1245  fSignals->Clr(sig);
1246  sigdone = sig;
1247  fSigcnt--;
1248  }
1249  if (sh->IsActive())
1250  sh->Notify();
1251  }
1252  }
1253  }
1254  }
1255  if (sigdone != -1)
1256  return kTRUE;
1257 
1258  return kFALSE;
1259 }
1260 
1261 ////////////////////////////////////////////////////////////////////////////////
1262 /// Check if children have finished.
1263 
1265 {
1266 #if 0 //rdm
1267  int pid;
1268  while ((pid = UnixWaitchild()) > 0) {
1269  TIter next(zombieHandler);
1270  register UnixPtty *pty;
1271  while ((pty = (UnixPtty*) next()))
1272  if (pty->GetPid() == pid) {
1273  zombieHandler->RemovePtr(pty);
1274  pty->DiedNotify();
1275  }
1276  }
1277 #endif
1278 }
1279 
1280 ////////////////////////////////////////////////////////////////////////////////
1281 /// Check if there is activity on some file descriptors and call their
1282 /// Notify() member.
1283 
1285 {
1286  TFileHandler *fh;
1287  Int_t fddone = -1;
1288  Bool_t read = kFALSE;
1290  while ((fh = (TFileHandler*) it.Next())) {
1291  Int_t fd = fh->GetFd();
1292  if ((fd <= fMaxrfd && fReadready->IsSet(fd) && fddone == -1) ||
1293  (fddone == fd && read)) {
1294  if (fddone == -1) {
1295  fReadready->Clr(fd);
1296  fddone = fd;
1297  read = kTRUE;
1298  fNfd--;
1299  }
1300  if (fh->IsActive())
1301  fh->ReadNotify();
1302  }
1303  if ((fd <= fMaxwfd && fWriteready->IsSet(fd) && fddone == -1) ||
1304  (fddone == fd && !read)) {
1305  if (fddone == -1) {
1306  fWriteready->Clr(fd);
1307  fddone = fd;
1308  read = kFALSE;
1309  fNfd--;
1310  }
1311  if (fh->IsActive())
1312  fh->WriteNotify();
1313  }
1314  }
1315  if (fddone != -1)
1316  return kTRUE;
1317 
1318  return kFALSE;
1319 }
1320 
1321 //---- Directories -------------------------------------------------------------
1322 
1323 ////////////////////////////////////////////////////////////////////////////////
1324 /// Make a Unix file system directory. Returns 0 in case of success and
1325 /// -1 if the directory could not be created.
1326 
1327 int TUnixSystem::MakeDirectory(const char *name)
1328 {
1329  TSystem *helper = FindHelper(name);
1330  if (helper)
1331  return helper->MakeDirectory(name);
1332 
1333  return UnixMakedir(name);
1334 }
1335 
1336 ////////////////////////////////////////////////////////////////////////////////
1337 /// Open a Unix file system directory. Returns 0 if directory does not exist.
1338 
1339 void *TUnixSystem::OpenDirectory(const char *name)
1340 {
1341  TSystem *helper = FindHelper(name);
1342  if (helper)
1343  return helper->OpenDirectory(name);
1344 
1345  return UnixOpendir(name);
1346 }
1347 
1348 ////////////////////////////////////////////////////////////////////////////////
1349 /// Close a Unix file system directory.
1350 
1352 {
1353  TSystem *helper = FindHelper(0, dirp);
1354  if (helper) {
1355  helper->FreeDirectory(dirp);
1356  return;
1357  }
1358 
1359  if (dirp)
1360  ::closedir((DIR*)dirp);
1361 }
1362 
1363 ////////////////////////////////////////////////////////////////////////////////
1364 /// Get next Unix file system directory entry. Returns 0 if no more entries.
1365 
1366 const char *TUnixSystem::GetDirEntry(void *dirp)
1367 {
1368  TSystem *helper = FindHelper(0, dirp);
1369  if (helper)
1370  return helper->GetDirEntry(dirp);
1371 
1372  if (dirp)
1373  return UnixGetdirentry(dirp);
1374 
1375  return 0;
1376 }
1377 
1378 ////////////////////////////////////////////////////////////////////////////////
1379 /// Change directory. Returns kTRUE in case of success, kFALSE otherwise.
1380 
1382 {
1383  Bool_t ret = (Bool_t) (::chdir(path) == 0);
1384  if (fWdpath != "")
1385  fWdpath = ""; // invalidate path cache
1386  return ret;
1387 }
1388 
1389 ////////////////////////////////////////////////////////////////////////////////
1390 /// Return working directory.
1391 
1393 {
1394  // don't use cache as user can call chdir() directly somewhere else
1395  //if (fWdpath != "")
1396  // return fWdpath.Data();
1397 
1399 
1400  static char cwd[kMAXPATHLEN];
1401  FillWithCwd(cwd);
1402  fWdpath = cwd;
1403 
1404  return fWdpath.Data();
1405 }
1406 
1407 //////////////////////////////////////////////////////////////////////////////
1408 /// Return working directory.
1409 
1411 {
1412  char cwd[kMAXPATHLEN];
1413  FillWithCwd(cwd);
1414  return std::string(cwd);
1415 }
1416 
1417 //////////////////////////////////////////////////////////////////////////////
1418 /// Fill buffer with current working directory.
1419 
1420 void TUnixSystem::FillWithCwd(char *cwd) const
1421 {
1422  if (::getcwd(cwd, kMAXPATHLEN) == 0) {
1423  Error("WorkingDirectory", "getcwd() failed");
1424  }
1425 }
1426 
1427 ////////////////////////////////////////////////////////////////////////////////
1428 /// Return the user's home directory.
1429 
1430 const char *TUnixSystem::HomeDirectory(const char *userName)
1431 {
1432  return UnixHomedirectory(userName);
1433 }
1434 
1435 //////////////////////////////////////////////////////////////////////////////
1436 /// Return the user's home directory.
1437 
1438 std::string TUnixSystem::GetHomeDirectory(const char *userName) const
1439 {
1440  char path[kMAXPATHLEN], mydir[kMAXPATHLEN] = { '\0' };
1441  auto res = UnixHomedirectory(userName, path, mydir);
1442  if (res) return std::string(res);
1443  else return std::string();
1444 }
1445 
1446 ////////////////////////////////////////////////////////////////////////////////
1447 /// Return a user configured or systemwide directory to create
1448 /// temporary files in.
1449 
1450 const char *TUnixSystem::TempDirectory() const
1451 {
1452  const char *dir = gSystem->Getenv("TMPDIR");
1453  if (!dir || gSystem->AccessPathName(dir, kWritePermission))
1454  dir = "/tmp";
1455 
1456  return dir;
1457 }
1458 
1459 ////////////////////////////////////////////////////////////////////////////////
1460 /// Create a secure temporary file by appending a unique
1461 /// 6 letter string to base. The file will be created in
1462 /// a standard (system) directory or in the directory
1463 /// provided in dir. The full filename is returned in base
1464 /// and a filepointer is returned for safely writing to the file
1465 /// (this avoids certain security problems). Returns 0 in case
1466 /// of error.
1467 
1468 FILE *TUnixSystem::TempFileName(TString &base, const char *dir)
1469 {
1470  char *b = ConcatFileName(dir ? dir : TempDirectory(), base);
1471  base = b;
1472  base += "XXXXXX";
1473  delete [] b;
1474 
1475  char *arg = StrDup(base);
1476  int fd = mkstemp(arg);
1477  base = arg;
1478  delete [] arg;
1479 
1480  if (fd == -1) {
1481  SysError("TempFileName", "%s", base.Data());
1482  return 0;
1483  } else {
1484  FILE *fp = fdopen(fd, "w+");
1485  if (fp == 0)
1486  SysError("TempFileName", "converting filedescriptor (%d)", fd);
1487  return fp;
1488  }
1489 }
1490 
1491 ////////////////////////////////////////////////////////////////////////////////
1492 /// Concatenate a directory and a file name.
1493 
1494 const char *TUnixSystem::PrependPathName(const char *dir, TString& name)
1495 {
1496  if (name.IsNull() || name == ".") {
1497  if (dir) {
1498  name = dir;
1499  if (dir[strlen(dir) - 1] != '/')
1500  name += '/';
1501  } else name = "";
1502  return name.Data();
1503  }
1504 
1505  if (!dir || !dir[0]) dir = "/";
1506  else if (dir[strlen(dir) - 1] != '/')
1507  name.Prepend('/');
1508  name.Prepend(dir);
1509 
1510  return name.Data();
1511 }
1512 
1513 //---- Paths & Files -----------------------------------------------------------
1514 
1515 ////////////////////////////////////////////////////////////////////////////////
1516 /// Returns FALSE if one can access a file using the specified access mode.
1517 /// Mode is the same as for the Unix access(2) function.
1518 /// Attention, bizarre convention of return value!!
1519 
1521 {
1522  TSystem *helper = FindHelper(path);
1523  if (helper)
1524  return helper->AccessPathName(path, mode);
1525 
1526  if (::access(StripOffProto(path, "file:"), mode) == 0)
1527  return kFALSE;
1529 
1530  return kTRUE;
1531 }
1532 
1533 ////////////////////////////////////////////////////////////////////////////////
1534 /// Copy a file. If overwrite is true and file already exists the
1535 /// file will be overwritten. Returns 0 when successful, -1 in case
1536 /// of file open failure, -2 in case the file already exists and overwrite
1537 /// was false and -3 in case of error during copy.
1538 
1539 int TUnixSystem::CopyFile(const char *f, const char *t, Bool_t overwrite)
1540 {
1541  if (!AccessPathName(t) && !overwrite)
1542  return -2;
1543 
1544  FILE *from = fopen(f, "r");
1545  if (!from)
1546  return -1;
1547 
1548  FILE *to = fopen(t, "w");
1549  if (!to) {
1550  fclose(from);
1551  return -1;
1552  }
1553 
1554  const int bufsize = 1024;
1555  char buf[bufsize];
1556  int ret = 0;
1557  while (!ret && !feof(from)) {
1558  size_t numread = fread (buf, sizeof(char), bufsize, from);
1559  size_t numwritten = fwrite(buf, sizeof(char), numread, to);
1560  if (numread != numwritten)
1561  ret = -3;
1562  }
1563 
1564  fclose(from);
1565  fclose(to);
1566 
1567  return ret;
1568 }
1569 
1570 ////////////////////////////////////////////////////////////////////////////////
1571 /// Rename a file. Returns 0 when successful, -1 in case of failure.
1572 
1573 int TUnixSystem::Rename(const char *f, const char *t)
1574 {
1575  int ret = ::rename(f, t);
1577  return ret;
1578 }
1579 
1580 ////////////////////////////////////////////////////////////////////////////////
1581 /// Returns TRUE if the url in 'path' points to the local file system.
1582 /// This is used to avoid going through the NIC card for local operations.
1583 
1585 {
1586  TSystem *helper = FindHelper(path);
1587  if (helper)
1588  return helper->IsPathLocal(path);
1589 
1590  return TSystem::IsPathLocal(path);
1591 }
1592 
1593 ////////////////////////////////////////////////////////////////////////////////
1594 /// Get info about a file. Info is returned in the form of a FileStat_t
1595 /// structure (see TSystem.h).
1596 /// The function returns 0 in case of success and 1 if the file could
1597 /// not be stat'ed.
1598 
1599 int TUnixSystem::GetPathInfo(const char *path, FileStat_t &buf)
1600 {
1601  TSystem *helper = FindHelper(path);
1602  if (helper)
1603  return helper->GetPathInfo(path, buf);
1604 
1605  return UnixFilestat(path, buf);
1606 }
1607 
1608 ////////////////////////////////////////////////////////////////////////////////
1609 /// Get info about a file system: id, bsize, bfree, blocks.
1610 /// Id is file system type (machine dependend, see statfs())
1611 /// Bsize is block size of file system
1612 /// Blocks is total number of blocks in file system
1613 /// Bfree is number of free blocks in file system
1614 /// The function returns 0 in case of success and 1 if the file system could
1615 /// not be stat'ed.
1616 
1617 int TUnixSystem::GetFsInfo(const char *path, Long_t *id, Long_t *bsize,
1618  Long_t *blocks, Long_t *bfree)
1619 {
1620  return UnixFSstat(path, id, bsize, blocks, bfree);
1621 }
1622 
1623 ////////////////////////////////////////////////////////////////////////////////
1624 /// Create a link from file1 to file2. Returns 0 when successful,
1625 /// -1 in case of failure.
1626 
1627 int TUnixSystem::Link(const char *from, const char *to)
1628 {
1629  return ::link(from, to);
1630 }
1631 
1632 ////////////////////////////////////////////////////////////////////////////////
1633 /// Create a symlink from file1 to file2. Returns 0 when successful,
1634 /// -1 in case of failure.
1635 
1636 int TUnixSystem::Symlink(const char *from, const char *to)
1637 {
1638 #if defined(R__AIX)
1639  return ::symlink((char*)from, (char*)to);
1640 #else
1641  return ::symlink(from, to);
1642 #endif
1643 }
1644 
1645 ////////////////////////////////////////////////////////////////////////////////
1646 /// Unlink, i.e. remove, a file or directory. Returns 0 when successful,
1647 /// -1 in case of failure.
1648 
1649 int TUnixSystem::Unlink(const char *name)
1650 {
1651  TSystem *helper = FindHelper(name);
1652  if (helper)
1653  return helper->Unlink(name);
1654 
1655 #if defined(R__SEEK64)
1656  struct stat64 finfo;
1657  if (lstat64(name, &finfo) < 0)
1658 #else
1659  struct stat finfo;
1660  if (lstat(name, &finfo) < 0)
1661 #endif
1662  return -1;
1663 
1664  if (S_ISDIR(finfo.st_mode))
1665  return ::rmdir(name);
1666  else
1667  return ::unlink(name);
1668 }
1669 
1670 //---- expand the metacharacters as in the shell -------------------------------
1671 
1672 // expand the metacharacters as in the shell
1673 
1674 const char
1675 #ifdef G__OLDEXPAND
1676  kShellEscape = '\\',
1677  *kShellStuff = "(){}<>\"'",
1678 #endif
1679  *kShellMeta = "~*[]{}?$";
1680 
1681 
1682 #ifndef G__OLDEXPAND
1683 ////////////////////////////////////////////////////////////////////////////////
1684 /// Expand a pathname getting rid of special shell characters like ~.$, etc.
1685 /// For Unix/Win32 compatibility use $(XXX) instead of $XXX when using
1686 /// environment variables in a pathname. If compatibility is not an issue
1687 /// you can use on Unix directly $XXX. Returns kFALSE in case of success
1688 /// or kTRUE in case of error.
1689 
1691 {
1692  const char *p, *patbuf = (const char *)path;
1693 
1694  // skip leading blanks
1695  while (*patbuf == ' ')
1696  patbuf++;
1697 
1698  // any shell meta characters ?
1699  for (p = patbuf; *p; p++)
1700  if (strchr(kShellMeta, *p))
1701  goto expand;
1702 
1703  return kFALSE;
1704 
1705 expand:
1706  // replace $(XXX) by $XXX
1707  path.ReplaceAll("$(","$");
1708  path.ReplaceAll(")","");
1709 
1710  return ExpandFileName(path);
1711 }
1712 #endif
1713 
1714 #ifdef G__OLDEXPAND
1715 ////////////////////////////////////////////////////////////////////////////////
1716 /// Expand a pathname getting rid of special shell characters like ~.$, etc.
1717 /// For Unix/Win32 compatibility use $(XXX) instead of $XXX when using
1718 /// environment variables in a pathname. If compatibility is not an issue
1719 /// you can use on Unix directly $XXX. Returns kFALSE in case of success
1720 /// or kTRUE in case of error.
1721 
1723 {
1724  const char *patbuf = (const char *)patbuf0;
1725  const char *hd, *p;
1726  // char cmd[kMAXPATHLEN],
1727  char stuffedPat[kMAXPATHLEN], name[70];
1728  char *q;
1729  FILE *pf;
1730  int ch;
1731 
1732  // skip leading blanks
1733  while (*patbuf == ' ')
1734  patbuf++;
1735 
1736  // any shell meta characters ?
1737  for (p = patbuf; *p; p++)
1738  if (strchr(kShellMeta, *p))
1739  goto needshell;
1740 
1741  return kFALSE;
1742 
1743 needshell:
1744  // replace $(XXX) by $XXX
1745  patbuf0.ReplaceAll("$(","$");
1746  patbuf0.ReplaceAll(")","");
1747 
1748  // escape shell quote characters
1749  EscChar(patbuf, stuffedPat, sizeof(stuffedPat), (char*)kShellStuff, kShellEscape);
1750 
1751  TString cmd("echo ");
1752 
1753  // emulate csh -> popen executes sh
1754  if (stuffedPat[0] == '~') {
1755  if (stuffedPat[1] != '\0' && stuffedPat[1] != '/') {
1756  // extract user name
1757  for (p = &stuffedPat[1], q = name; *p && *p !='/';)
1758  *q++ = *p++;
1759  *q = '\0';
1760  hd = UnixHomedirectory(name);
1761  if (hd == 0)
1762  cmd += stuffedPat;
1763  else {
1764  cmd += hd;
1765  cmd += p;
1766  }
1767  } else {
1768  hd = UnixHomedirectory(0);
1769  if (hd == 0) {
1771  return kTRUE;
1772  }
1773  cmd += hd;
1774  cmd += &stuffedPat[1];
1775  }
1776  } else
1777  cmd += stuffedPat;
1778 
1779  if ((pf = ::popen(cmd.Data(), "r")) == 0) {
1781  return kTRUE;
1782  }
1783 
1784  // read first argument
1785  patbuf0 = "";
1786  int cnt = 0;
1787 #if defined(R__AIX)
1788 again:
1789 #endif
1790  for (ch = fgetc(pf); ch != EOF && ch != ' ' && ch != '\n'; ch = fgetc(pf)) {
1791  patbuf0.Append(ch);
1792  cnt++;
1793  }
1794 #if defined(R__AIX)
1795  // Work around bug timing problem due to delay in forking a large program
1796  if (cnt == 0 && ch == EOF) goto again;
1797 #endif
1798 
1799  // skip rest of pipe
1800  while (ch != EOF) {
1801  ch = fgetc(pf);
1802  if (ch == ' ' || ch == '\t') {
1803  GetLastErrorString() = "expression ambigous";
1804  ::pclose(pf);
1805  return kTRUE;
1806  }
1807  }
1808 
1809  ::pclose(pf);
1810 
1811  return kFALSE;
1812 }
1813 #endif
1814 
1815 ////////////////////////////////////////////////////////////////////////////////
1816 /// Expand a pathname getting rid of special shell characaters like ~.$, etc.
1817 /// For Unix/Win32 compatibility use $(XXX) instead of $XXX when using
1818 /// environment variables in a pathname. If compatibility is not an issue
1819 /// you can use on Unix directly $XXX. The user must delete returned string.
1820 /// Returns the expanded pathname or 0 in case of error.
1821 /// The user must delete returned string (delete []).
1822 
1823 char *TUnixSystem::ExpandPathName(const char *path)
1824 {
1825  TString patbuf = path;
1826  if (ExpandPathName(patbuf))
1827  return 0;
1828  return StrDup(patbuf.Data());
1829 }
1830 
1831 ////////////////////////////////////////////////////////////////////////////////
1832 /// Set the file permission bits. Returns -1 in case or error, 0 otherwise.
1833 
1834 int TUnixSystem::Chmod(const char *file, UInt_t mode)
1835 {
1836  return ::chmod(file, mode);
1837 }
1838 
1839 ////////////////////////////////////////////////////////////////////////////////
1840 /// Set the process file creation mode mask.
1841 
1843 {
1844  return ::umask(mask);
1845 }
1846 
1847 ////////////////////////////////////////////////////////////////////////////////
1848 /// Set a files modification and access times. If actime = 0 it will be
1849 /// set to the modtime. Returns 0 on success and -1 in case of error.
1850 
1851 int TUnixSystem::Utime(const char *file, Long_t modtime, Long_t actime)
1852 {
1853  if (!actime)
1854  actime = modtime;
1855 
1856  struct utimbuf t;
1857  t.actime = (time_t)actime;
1858  t.modtime = (time_t)modtime;
1859  return ::utime(file, &t);
1860 }
1861 
1862 ////////////////////////////////////////////////////////////////////////////////
1863 /// Find location of file "wfil" in a search path.
1864 /// The search path is specified as a : separated list of directories.
1865 /// Return value is pointing to wfile for compatibility with
1866 /// Which(const char*,const char*,EAccessMode) version.
1867 
1868 const char *TUnixSystem::FindFile(const char *search, TString& wfil, EAccessMode mode)
1869 {
1870  TString show;
1871  if (gEnv->GetValue("Root.ShowPath", 0))
1872  show.Form("Which: %s =", wfil.Data());
1873 
1874  gSystem->ExpandPathName(wfil);
1875 
1876  if (wfil[0] == '/') {
1877 #if defined(R__SEEK64)
1878  struct stat64 finfo;
1879  if (access(wfil.Data(), mode) == 0 &&
1880  stat64(wfil.Data(), &finfo) == 0 && S_ISREG(finfo.st_mode)) {
1881 #else
1882  struct stat finfo;
1883  if (access(wfil.Data(), mode) == 0 &&
1884  stat(wfil.Data(), &finfo) == 0 && S_ISREG(finfo.st_mode)) {
1885 #endif
1886  if (show != "")
1887  Printf("%s %s", show.Data(), wfil.Data());
1888  return wfil.Data();
1889  }
1890  if (show != "")
1891  Printf("%s <not found>", show.Data());
1892  wfil = "";
1893  return 0;
1894  }
1895 
1896  if (search == 0)
1897  search = ".";
1898 
1899  TString apwd(gSystem->WorkingDirectory());
1900  apwd += "/";
1901  for (const char* ptr = search; *ptr;) {
1902  TString name;
1903  if (*ptr != '/' && *ptr !='$' && *ptr != '~')
1904  name = apwd;
1905  const char* posEndOfPart = strchr(ptr, ':');
1906  if (posEndOfPart) {
1907  name.Append(ptr, posEndOfPart - ptr);
1908  ptr = posEndOfPart + 1; // skip ':'
1909  } else {
1910  name.Append(ptr);
1911  ptr += strlen(ptr);
1912  }
1913 
1914  if (!name.EndsWith("/"))
1915  name += '/';
1916  name += wfil;
1917 
1918  gSystem->ExpandPathName(name);
1919 #if defined(R__SEEK64)
1920  struct stat64 finfo;
1921  if (access(name.Data(), mode) == 0 &&
1922  stat64(name.Data(), &finfo) == 0 && S_ISREG(finfo.st_mode)) {
1923 #else
1924  struct stat finfo;
1925  if (access(name.Data(), mode) == 0 &&
1926  stat(name.Data(), &finfo) == 0 && S_ISREG(finfo.st_mode)) {
1927 #endif
1928  if (show != "")
1929  Printf("%s %s", show.Data(), name.Data());
1930  wfil = name;
1931  return wfil.Data();
1932  }
1933  }
1934 
1935  if (show != "")
1936  Printf("%s <not found>", show.Data());
1937  wfil = "";
1938  return 0;
1939 }
1940 
1941 //---- Users & Groups ----------------------------------------------------------
1942 
1943 ////////////////////////////////////////////////////////////////////////////////
1944 /// Returns the user's id. If user = 0, returns current user's id.
1945 
1946 Int_t TUnixSystem::GetUid(const char *user)
1947 {
1948  if (!user || !user[0])
1949  return getuid();
1950  else {
1951  struct passwd *apwd = getpwnam(user);
1952  if (apwd)
1953  return apwd->pw_uid;
1954  }
1955  return 0;
1956 }
1957 
1958 ////////////////////////////////////////////////////////////////////////////////
1959 /// Returns the effective user id. The effective id corresponds to the
1960 /// set id bit on the file being executed.
1961 
1963 {
1964  return geteuid();
1965 }
1966 
1967 ////////////////////////////////////////////////////////////////////////////////
1968 /// Returns the group's id. If group = 0, returns current user's group.
1969 
1971 {
1972  if (!group || !group[0])
1973  return getgid();
1974  else {
1975  struct group *grp = getgrnam(group);
1976  if (grp)
1977  return grp->gr_gid;
1978  }
1979  return 0;
1980 }
1981 
1982 ////////////////////////////////////////////////////////////////////////////////
1983 /// Returns the effective group id. The effective group id corresponds
1984 /// to the set id bit on the file being executed.
1985 
1987 {
1988  return getegid();
1989 }
1990 
1991 ////////////////////////////////////////////////////////////////////////////////
1992 /// Returns all user info in the UserGroup_t structure. The returned
1993 /// structure must be deleted by the user. In case of error 0 is returned.
1994 
1996 {
1997  typedef std::map<Int_t /*uid*/, UserGroup_t> UserInfoCache_t;
1998  static UserInfoCache_t gUserInfo;
1999 
2000  UserInfoCache_t::const_iterator iUserInfo = gUserInfo.find(uid);
2001  if (iUserInfo != gUserInfo.end())
2002  return new UserGroup_t(iUserInfo->second);
2003 
2004  struct passwd *apwd = getpwuid(uid);
2005  if (apwd) {
2006  UserGroup_t *ug = new UserGroup_t;
2007  ug->fUid = apwd->pw_uid;
2008  ug->fGid = apwd->pw_gid;
2009  ug->fUser = apwd->pw_name;
2010  ug->fPasswd = apwd->pw_passwd;
2011  ug->fRealName = apwd->pw_gecos;
2012  ug->fShell = apwd->pw_shell;
2013  UserGroup_t *gr = GetGroupInfo(apwd->pw_gid);
2014  if (gr) ug->fGroup = gr->fGroup;
2015  delete gr;
2016 
2017  gUserInfo[uid] = *ug;
2018  return ug;
2019  }
2020  return 0;
2021 }
2022 
2023 ////////////////////////////////////////////////////////////////////////////////
2024 /// Returns all user info in the UserGroup_t structure. If user = 0, returns
2025 /// current user's id info. The returned structure must be deleted by the
2026 /// user. In case of error 0 is returned.
2027 
2029 {
2030  return GetUserInfo(GetUid(user));
2031 }
2032 
2033 ////////////////////////////////////////////////////////////////////////////////
2034 /// Returns all group info in the UserGroup_t structure. The only active
2035 /// fields in the UserGroup_t structure for this call are:
2036 /// fGid and fGroup
2037 /// The returned structure must be deleted by the user. In case of
2038 /// error 0 is returned.
2039 
2041 {
2042  struct group *grp = getgrgid(gid);
2043  if (grp) {
2044  UserGroup_t *gr = new UserGroup_t;
2045  gr->fUid = 0;
2046  gr->fGid = grp->gr_gid;
2047  gr->fGroup = grp->gr_name;
2048  return gr;
2049  }
2050  return 0;
2051 }
2052 
2053 ////////////////////////////////////////////////////////////////////////////////
2054 /// Returns all group info in the UserGroup_t structure. The only active
2055 /// fields in the UserGroup_t structure for this call are:
2056 /// fGid and fGroup
2057 /// If group = 0, returns current user's group. The returned structure
2058 /// must be deleted by the user. In case of error 0 is returned.
2059 
2061 {
2062  return GetGroupInfo(GetGid(group));
2063 }
2064 
2065 //---- environment manipulation ------------------------------------------------
2066 
2067 ////////////////////////////////////////////////////////////////////////////////
2068 /// Set environment variable.
2069 
2070 void TUnixSystem::Setenv(const char *name, const char *value)
2071 {
2072  ::setenv(name, value, 1);
2073 }
2074 
2075 ////////////////////////////////////////////////////////////////////////////////
2076 /// Get environment variable.
2077 
2078 const char *TUnixSystem::Getenv(const char *name)
2079 {
2080  return ::getenv(name);
2081 }
2082 
2083 ////////////////////////////////////////////////////////////////////////////////
2084 /// Unset environment variable.
2085 
2086 void TUnixSystem::Unsetenv(const char *name)
2087 {
2088  ::unsetenv(name);
2089 }
2090 
2091 //---- Processes ---------------------------------------------------------------
2092 
2093 ////////////////////////////////////////////////////////////////////////////////
2094 /// Execute a command.
2095 
2096 int TUnixSystem::Exec(const char *shellcmd)
2097 {
2098  return ::system(shellcmd);
2099 }
2100 
2101 ////////////////////////////////////////////////////////////////////////////////
2102 /// Open a pipe.
2103 
2104 FILE *TUnixSystem::OpenPipe(const char *command, const char *mode)
2105 {
2106  return ::popen(command, mode);
2107 }
2108 
2109 ////////////////////////////////////////////////////////////////////////////////
2110 /// Close the pipe.
2111 
2112 int TUnixSystem::ClosePipe(FILE *pipe)
2113 {
2114  return ::pclose(pipe);
2115 }
2116 
2117 ////////////////////////////////////////////////////////////////////////////////
2118 /// Get process id.
2119 
2121 {
2122  return ::getpid();
2123 }
2124 
2125 ////////////////////////////////////////////////////////////////////////////////
2126 /// Exit the application.
2127 
2128 void TUnixSystem::Exit(int code, Bool_t mode)
2129 {
2130  // Insures that the files and sockets are closed before any library is unloaded
2131  // and before emptying CINT.
2132  if (gROOT) {
2133  gROOT->EndOfProcessCleanups();
2134  } else if (gInterpreter) {
2135  gInterpreter->ResetGlobals();
2136  }
2137 
2138  if (mode)
2139  ::exit(code);
2140  else
2141  ::_exit(code);
2142 }
2143 
2144 ////////////////////////////////////////////////////////////////////////////////
2145 /// Abort the application.
2146 
2148 {
2149  ::abort();
2150 }
2151 
2152 ////////////////////////////////////////////////////////////////////////////////
2153 /// Print a stack trace.
2154 
2156 {
2157  if (!gEnv->GetValue("Root.Stacktrace", 1))
2158  return;
2159 
2160  TString gdbscript = gEnv->GetValue("Root.StacktraceScript", "");
2161  gdbscript = gdbscript.Strip();
2162  if (gdbscript != "") {
2163  if (AccessPathName(gdbscript, kReadPermission)) {
2164  fprintf(stderr, "Root.StacktraceScript %s does not exist\n", gdbscript.Data());
2165  gdbscript = "";
2166  } else {
2167  gdbscript += " ";
2168  }
2169  }
2170  if (gdbscript == "") {
2171 #ifdef ROOTETCDIR
2172  gdbscript.Form("%s/gdb-backtrace.sh", ROOTETCDIR);
2173 #else
2174  gdbscript.Form("%s/etc/gdb-backtrace.sh", Getenv("ROOTSYS"));
2175 #endif
2176  if (AccessPathName(gdbscript, kReadPermission)) {
2177  fprintf(stderr, "Error in <TUnixSystem::StackTrace> script %s is missing\n", gdbscript.Data());
2178  return;
2179  }
2180  gdbscript += " ";
2181  }
2182 
2183  TString gdbmess = gEnv->GetValue("Root.StacktraceMessage", "");
2184  gdbmess = gdbmess.Strip();
2185 
2186  std::cout.flush();
2187  fflush(stdout);
2188 
2189  std::cerr.flush();
2190  fflush(stderr);
2191 
2192  int fd = STDERR_FILENO;
2193 
2194  const char *message = " Generating stack trace...\n";
2195 
2196  if (fd && message) { } // remove unused warning (remove later)
2197 
2198  if (gApplication && !strcmp(gApplication->GetName(), "TRint"))
2199  Getlinem(kCleanUp, 0);
2200 
2201 #if defined(USE_GDB_STACK_TRACE)
2202  char *gdb = Which(Getenv("PATH"), "gdb", kExecutePermission);
2203  if (!gdb) {
2204  fprintf(stderr, "gdb not found, need it for stack trace\n");
2205  return;
2206  }
2207 
2208  // write custom message file
2209  TString gdbmessf = "gdb-message";
2210  if (gdbmess != "") {
2211  FILE *f = TempFileName(gdbmessf);
2212  fprintf(f, "%s\n", gdbmess.Data());
2213  fclose(f);
2214  }
2215 
2216  // use gdb to get stack trace
2217  gdbscript += GetExePath();
2218  gdbscript += " ";
2219  gdbscript += GetPid();
2220  if (gdbmess != "") {
2221  gdbscript += " ";
2222  gdbscript += gdbmessf;
2223  }
2224  gdbscript += " 1>&2";
2225  Exec(gdbscript);
2226  delete [] gdb;
2227  return;
2228 
2229 #elif defined(R__AIX)
2230  TString script = "procstack ";
2231  script += GetPid();
2232  Exec(script);
2233  return;
2234 #elif defined(R__SOLARIS)
2235  char *cppfilt = Which(Getenv("PATH"), "c++filt", kExecutePermission);
2236  TString script = "pstack ";
2237  script += GetPid();
2238  if (cppfilt) {
2239  script += " | ";
2240  script += cppfilt;
2241  delete [] cppfilt;
2242  }
2243  Exec(script);
2244  return;
2245 #elif defined(HAVE_BACKTRACE_SYMBOLS_FD) && defined(HAVE_DLADDR) // linux + MacOS X >= 10.5
2246  // we could have used backtrace_symbols_fd, except its output
2247  // format is pretty bad, so recode that here :-(
2248 
2249  // take care of demangling
2250  Bool_t demangle = kTRUE;
2251 
2252  // check for c++filt
2253  const char *cppfilt = "c++filt";
2254  const char *cppfiltarg = "";
2255 #ifdef R__B64
2256  const char *format1 = " 0x%016lx in %.200s %s 0x%lx from %.200s\n";
2257 #ifdef R__MACOSX
2258  const char *format2 = " 0x%016lx in %.200s\n";
2259 #else
2260  const char *format2 = " 0x%016lx in %.200s at %.200s from %.200s\n";
2261 #endif
2262  const char *format3 = " 0x%016lx in %.200s from %.200s\n";
2263  const char *format4 = " 0x%016lx in <unknown function>\n";
2264 #else
2265  const char *format1 = " 0x%08lx in %.200s %s 0x%lx from %.200s\n";
2266 #ifdef R__MACOSX
2267  const char *format2 = " 0x%08lx in %.200s\n";
2268 #else
2269  const char *format2 = " 0x%08lx in %.200s at %.200s from %.200s\n";
2270 #endif
2271  const char *format3 = " 0x%08lx in %.200s from %.200s\n";
2272  const char *format4 = " 0x%08lx in <unknown function>\n";
2273 #endif
2274 
2275  char *filter = Which(Getenv("PATH"), cppfilt, kExecutePermission);
2276  if (!filter)
2277  demangle = kFALSE;
2278 
2279 #if (__GNUC__ >= 3)
2280  // try finding supported format option for g++ v3
2281  if (filter) {
2282  FILE *p = OpenPipe(TString::Format("%s --help 2>&1", filter), "r");
2283  TString help;
2284  while (help.Gets(p)) {
2285  if (help.Index("gnu-v3") != kNPOS) {
2286  cppfiltarg = "--format=gnu-v3";
2287  break;
2288  } else if (help.Index("gnu-new-abi") != kNPOS) {
2289  cppfiltarg = "--format=gnu-new-abi";
2290  break;
2291  }
2292  }
2293  ClosePipe(p);
2294  }
2295 #endif
2296  // gdb-backtrace.sh uses gdb to produce a backtrace. See if it is available.
2297  // If it is, use it. If not proceed as before.
2298 #if (defined(R__LINUX) && !defined(R__WINGCC))
2299  // Declare the process that will be generating the stacktrace
2300  // For more see: http://askubuntu.com/questions/41629/after-upgrade-gdb-wont-attach-to-process
2301 #ifdef PR_SET_PTRACER
2302  prctl(PR_SET_PTRACER, getpid(), 0, 0, 0);
2303 #endif
2304 #endif
2305  char *gdb = Which(Getenv("PATH"), "gdb", kExecutePermission);
2306  if (gdb) {
2307  // write custom message file
2308  TString gdbmessf = "gdb-message";
2309  if (gdbmess != "") {
2310  FILE *f = TempFileName(gdbmessf);
2311  fprintf(f, "%s\n", gdbmess.Data());
2312  fclose(f);
2313  }
2314 
2315  // use gdb to get stack trace
2316 #ifdef R__MACOSX
2317  gdbscript += GetExePath();
2318  gdbscript += " ";
2319 #endif
2320  gdbscript += GetPid();
2321  if (gdbmess != "") {
2322  gdbscript += " ";
2323  gdbscript += gdbmessf;
2324  }
2325  gdbscript += " 1>&2";
2326  Exec(gdbscript);
2327  delete [] gdb;
2328  } else {
2329  // addr2line uses debug info to convert addresses into file names
2330  // and line numbers
2331 #ifdef R__MACOSX
2332  char *addr2line = Which(Getenv("PATH"), "atos", kExecutePermission);
2333 #else
2334  char *addr2line = Which(Getenv("PATH"), "addr2line", kExecutePermission);
2335 #endif
2336  if (addr2line) {
2337  // might take some time so tell what we are doing...
2338  if (write(fd, message, strlen(message)) < 0)
2339  Warning("StackTrace", "problems writing line numbers (errno: %d)", TSystem::GetErrno());
2340  }
2341 
2342  // open tmp file for demangled stack trace
2343  TString tmpf1 = "gdb-backtrace";
2344  std::ofstream file1;
2345  if (demangle) {
2346  FILE *f = TempFileName(tmpf1);
2347  if (f) fclose(f);
2348  file1.open(tmpf1);
2349  if (!file1) {
2350  Error("StackTrace", "could not open file %s", tmpf1.Data());
2351  Unlink(tmpf1);
2352  demangle = kFALSE;
2353  }
2354  }
2355 
2356 #ifdef R__MACOSX
2357  if (addr2line)
2358  demangle = kFALSE; // atos always demangles
2359 #endif
2360 
2361  char buffer[4096];
2362  void *trace[kMAX_BACKTRACE_DEPTH];
2363  int depth = backtrace(trace, kMAX_BACKTRACE_DEPTH);
2364  for (int n = 5; n < depth; n++) {
2365  ULong_t addr = (ULong_t) trace[n];
2366  Dl_info info;
2367 
2368  if (dladdr(trace[n], &info) && info.dli_fname && info.dli_fname[0]) {
2369  const char *libname = info.dli_fname;
2370  const char *symname = (info.dli_sname && info.dli_sname[0]) ?
2371  info.dli_sname : "<unknown>";
2372  ULong_t libaddr = (ULong_t) info.dli_fbase;
2373  ULong_t symaddr = (ULong_t) info.dli_saddr;
2374  Bool_t gte = (addr >= symaddr);
2375  ULong_t diff = (gte) ? addr - symaddr : symaddr - addr;
2376  if (addr2line && symaddr) {
2377  Bool_t nodebug = kTRUE;
2378 #ifdef R__MACOSX
2379  if (libaddr) { } // use libaddr
2380 #if defined(MAC_OS_X_VERSION_10_10)
2381  snprintf(buffer, sizeof(buffer), "%s -p %d 0x%016lx", addr2line, GetPid(), addr);
2382 #elif defined(MAC_OS_X_VERSION_10_9)
2383  // suppress deprecation warning with opti
2384  snprintf(buffer, sizeof(buffer), "%s -d -p %d 0x%016lx", addr2line, GetPid(), addr);
2385 #else
2386  snprintf(buffer, sizeof(buffer), "%s -p %d 0x%016lx", addr2line, GetPid(), addr);
2387 #endif
2388 #else
2389  ULong_t offset = (addr >= libaddr) ? addr - libaddr :
2390  libaddr - addr;
2391  TString name = TString(libname);
2392  Bool_t noPath = kFALSE;
2393  Bool_t noShare = kTRUE;
2394  if (name[0] != '/') noPath = kTRUE;
2395  if (name.Contains(".so") || name.Contains(".sl")) noShare = kFALSE;
2396  if (noShare) offset = addr;
2397  if (noPath) name = "`which " + name + "`";
2398  snprintf(buffer, sizeof(buffer), "%s -e %s 0x%016lx", addr2line, name.Data(), offset);
2399 #endif
2400  if (FILE *pf = ::popen(buffer, "r")) {
2401  char buf[2048];
2402  if (fgets(buf, 2048, pf)) {
2403  buf[strlen(buf)-1] = 0; // remove trailing \n
2404  if (strncmp(buf, "??", 2)) {
2405 #ifdef R__MACOSX
2406  snprintf(buffer, sizeof(buffer), format2, addr, buf);
2407 #else
2408  snprintf(buffer, sizeof(buffer), format2, addr, symname, buf, libname);
2409 #endif
2410  nodebug = kFALSE;
2411  }
2412  }
2413  ::pclose(pf);
2414  }
2415  if (nodebug)
2416  snprintf(buffer, sizeof(buffer), format1, addr, symname,
2417  gte ? "+" : "-", diff, libname);
2418  } else {
2419  if (symaddr)
2420  snprintf(buffer, sizeof(buffer), format1, addr, symname,
2421  gte ? "+" : "-", diff, libname);
2422  else
2423  snprintf(buffer, sizeof(buffer), format3, addr, symname, libname);
2424  }
2425  } else {
2426  snprintf(buffer, sizeof(buffer), format4, addr);
2427  }
2428 
2429  if (demangle)
2430  file1 << buffer;
2431  else
2432  if (write(fd, buffer, ::strlen(buffer)) < 0)
2433  Warning("StackTrace", "problems writing buffer (errno: %d)", TSystem::GetErrno());
2434  }
2435 
2436  if (demangle) {
2437  TString tmpf2 = "gdb-backtrace";
2438  FILE *f = TempFileName(tmpf2);
2439  if (f) fclose(f);
2440  file1.close();
2441  snprintf(buffer, sizeof(buffer), "%s %s < %s > %s", filter, cppfiltarg, tmpf1.Data(), tmpf2.Data());
2442  Exec(buffer);
2443  std::ifstream file2(tmpf2);
2444  TString line;
2445  while (file2) {
2446  line = "";
2447  line.ReadString(file2);
2448  if (write(fd, line.Data(), line.Length()) < 0)
2449  Warning("StackTrace", "problems writing line (errno: %d)", TSystem::GetErrno());
2450  }
2451  file2.close();
2452  Unlink(tmpf1);
2453  Unlink(tmpf2);
2454  }
2455 
2456  delete [] addr2line;
2457  }
2458  delete [] filter;
2459 #elif defined(HAVE_EXCPT_H) && defined(HAVE_PDSC_H) && \
2460  defined(HAVE_RLD_INTERFACE_H) // tru64
2461  // Tru64 stack walk. Uses the exception handling library and the
2462  // run-time linker's core functions (loader(5)). FIXME: Tru64
2463  // should have _RLD_DLADDR like IRIX below. Verify and update.
2464 
2465  char buffer [128];
2466  sigcontext context;
2467  int rc = 0;
2468 
2469  exc_capture_context (&context);
2470  while (!rc && context.sc_pc) {
2471  // FIXME: Elf32?
2472  pdsc_crd *func, *base, *crd
2473  = exc_remote_lookup_function_entry(0, 0, context.sc_pc, 0, &func, &base);
2474  Elf32_Addr addr = PDSC_CRD_BEGIN_ADDRESS(base, func);
2475  // const char *name = _rld_address_to_name(addr);
2476  const char *name = "<unknown function>";
2477  sprintf(buffer, " 0x%012lx %.200s + 0x%lx\n",
2478  context.sc_pc, name, context.sc_pc - addr);
2479  write(fd, buffer, ::strlen(buffer));
2480  rc = exc_virtual_unwind(0, &context);
2481  }
2482 #endif
2483 }
2484 
2485 //---- System Logging ----------------------------------------------------------
2486 
2487 ////////////////////////////////////////////////////////////////////////////////
2488 /// Open connection to system log daemon. For the use of the options and
2489 /// facility see the Unix openlog man page.
2490 
2491 void TUnixSystem::Openlog(const char *name, Int_t options, ELogFacility facility)
2492 {
2493  int fac = 0;
2494 
2495  switch (facility) {
2496  case kLogLocal0:
2497  fac = LOG_LOCAL0;
2498  break;
2499  case kLogLocal1:
2500  fac = LOG_LOCAL1;
2501  break;
2502  case kLogLocal2:
2503  fac = LOG_LOCAL2;
2504  break;
2505  case kLogLocal3:
2506  fac = LOG_LOCAL3;
2507  break;
2508  case kLogLocal4:
2509  fac = LOG_LOCAL4;
2510  break;
2511  case kLogLocal5:
2512  fac = LOG_LOCAL5;
2513  break;
2514  case kLogLocal6:
2515  fac = LOG_LOCAL6;
2516  break;
2517  case kLogLocal7:
2518  fac = LOG_LOCAL7;
2519  break;
2520  }
2521 
2522  ::openlog(name, options, fac);
2523 }
2524 
2525 ////////////////////////////////////////////////////////////////////////////////
2526 /// Send mess to syslog daemon. Level is the logging level and mess the
2527 /// message that will be written on the log.
2528 
2529 void TUnixSystem::Syslog(ELogLevel level, const char *mess)
2530 {
2531  // ELogLevel matches exactly the Unix values.
2532  ::syslog(level, "%s", mess);
2533 }
2534 
2535 ////////////////////////////////////////////////////////////////////////////////
2536 /// Close connection to system log daemon.
2537 
2539 {
2540  ::closelog();
2541 }
2542 
2543 //---- Standard output redirection ---------------------------------------------
2544 
2545 ////////////////////////////////////////////////////////////////////////////////
2546 /// Redirect standard output (stdout, stderr) to the specified file.
2547 /// If the file argument is 0 the output is set again to stderr, stdout.
2548 /// The second argument specifies whether the output should be added to the
2549 /// file ("a", default) or the file be truncated before ("w").
2550 /// This function saves internally the current state into a static structure.
2551 /// The call can be made reentrant by specifying the opaque structure pointed
2552 /// by 'h', which is filled with the relevant information. The handle 'h'
2553 /// obtained on the first call must then be used in any subsequent call,
2554 /// included ShowOutput, to display the redirected output.
2555 /// Returns 0 on success, -1 in case of error.
2556 
2557 Int_t TUnixSystem::RedirectOutput(const char *file, const char *mode,
2559 {
2560  // Instance to be used if the caller does not passes 'h'
2561  static RedirectHandle_t loch;
2562 
2563  Int_t rc = 0;
2564 
2565  // Which handle to use ?
2566  RedirectHandle_t *xh = (h) ? h : &loch;
2567 
2568  if (file) {
2569  // Save the paths
2570  Bool_t outdone = kFALSE;
2571  if (xh->fStdOutTty.IsNull()) {
2572  const char *tty = ttyname(STDOUT_FILENO);
2573  if (tty) {
2574  xh->fStdOutTty = tty;
2575  } else {
2576  if ((xh->fStdOutDup = dup(STDOUT_FILENO)) < 0) {
2577  SysError("RedirectOutput", "could not 'dup' stdout (errno: %d)", TSystem::GetErrno());
2578  return -1;
2579  }
2580  outdone = kTRUE;
2581  }
2582  }
2583  if (xh->fStdErrTty.IsNull()) {
2584  const char *tty = ttyname(STDERR_FILENO);
2585  if (tty) {
2586  xh->fStdErrTty = tty;
2587  } else {
2588  if ((xh->fStdErrDup = dup(STDERR_FILENO)) < 0) {
2589  SysError("RedirectOutput", "could not 'dup' stderr (errno: %d)", TSystem::GetErrno());
2590  if (outdone && dup2(xh->fStdOutDup, STDOUT_FILENO) < 0) {
2591  Warning("RedirectOutput", "could not restore stdout (back to original redirected"
2592  " file) (errno: %d)", TSystem::GetErrno());
2593  }
2594  return -1;
2595  }
2596  }
2597  }
2598 
2599  // Make sure mode makes sense; default "a"
2600  const char *m = (mode[0] == 'a' || mode[0] == 'w') ? mode : "a";
2601 
2602  // Current file size
2603  xh->fReadOffSet = 0;
2604  if (m[0] == 'a') {
2605  // If the file exists, save the current size
2606  FileStat_t st;
2607  if (!gSystem->GetPathInfo(file, st))
2608  xh->fReadOffSet = (st.fSize > 0) ? st.fSize : xh->fReadOffSet;
2609  }
2610  xh->fFile = file;
2611 
2612  // Redirect stdout & stderr
2613  if (freopen(file, m, stdout) == 0) {
2614  SysError("RedirectOutput", "could not freopen stdout (errno: %d)", TSystem::GetErrno());
2615  return -1;
2616  }
2617  if (freopen(file, m, stderr) == 0) {
2618  SysError("RedirectOutput", "could not freopen stderr (errno: %d)", TSystem::GetErrno());
2619  if (freopen(xh->fStdOutTty.Data(), "a", stdout) == 0)
2620  SysError("RedirectOutput", "could not restore stdout (errno: %d)", TSystem::GetErrno());
2621  return -1;
2622  }
2623  } else {
2624  // Restore stdout & stderr
2625  fflush(stdout);
2626  if (!(xh->fStdOutTty.IsNull())) {
2627  if (freopen(xh->fStdOutTty.Data(), "a", stdout) == 0) {
2628  SysError("RedirectOutput", "could not restore stdout (errno: %d)", TSystem::GetErrno());
2629  rc = -1;
2630  }
2631  xh->fStdOutTty = "";
2632  } else {
2633  if (close(STDOUT_FILENO) != 0) {
2634  SysError("RedirectOutput",
2635  "problems closing STDOUT_FILENO (%d) before 'dup2' (errno: %d)",
2636  STDOUT_FILENO, TSystem::GetErrno());
2637  rc = -1;
2638  }
2639  if (dup2(xh->fStdOutDup, STDOUT_FILENO) < 0) {
2640  SysError("RedirectOutput", "could not restore stdout (back to original redirected"
2641  " file) (errno: %d)", TSystem::GetErrno());
2642  rc = -1;
2643  }
2644  if (close(xh->fStdOutDup) != 0) {
2645  SysError("RedirectOutput",
2646  "problems closing temporary 'out' descriptor %d (errno: %d)",
2647  TSystem::GetErrno(), xh->fStdOutDup);
2648  rc = -1;
2649  }
2650  }
2651  fflush(stderr);
2652  if (!(xh->fStdErrTty.IsNull())) {
2653  if (freopen(xh->fStdErrTty.Data(), "a", stderr) == 0) {
2654  SysError("RedirectOutput", "could not restore stderr (errno: %d)", TSystem::GetErrno());
2655  rc = -1;
2656  }
2657  xh->fStdErrTty = "";
2658  } else {
2659  if (close(STDERR_FILENO) != 0) {
2660  SysError("RedirectOutput",
2661  "problems closing STDERR_FILENO (%d) before 'dup2' (errno: %d)",
2662  STDERR_FILENO, TSystem::GetErrno());
2663  rc = -1;
2664  }
2665  if (dup2(xh->fStdErrDup, STDERR_FILENO) < 0) {
2666  SysError("RedirectOutput", "could not restore stderr (back to original redirected"
2667  " file) (errno: %d)", TSystem::GetErrno());
2668  rc = -1;
2669  }
2670  if (close(xh->fStdErrDup) != 0) {
2671  SysError("RedirectOutput",
2672  "problems closing temporary 'err' descriptor %d (errno: %d)",
2673  TSystem::GetErrno(), xh->fStdErrDup);
2674  rc = -1;
2675  }
2676  }
2677  // Reset the static instance, if using that
2678  if (xh == &loch)
2679  xh->Reset();
2680  }
2681  return rc;
2682 }
2683 
2684 //---- dynamic loading and linking ---------------------------------------------
2685 
2686 ////////////////////////////////////////////////////////////////////////////////
2687 ///dynamic linking of module
2688 
2689 Func_t TUnixSystem::DynFindSymbol(const char * /*module*/, const char *entry)
2690 {
2691  return TSystem::DynFindSymbol("*", entry);
2692 }
2693 
2694 ////////////////////////////////////////////////////////////////////////////////
2695 /// Load a shared library. Returns 0 on successful loading, 1 in
2696 /// case lib was already loaded and -1 in case lib does not exist
2697 /// or in case of error.
2698 
2699 int TUnixSystem::Load(const char *module, const char *entry, Bool_t system)
2700 {
2701  return TSystem::Load(module, entry, system);
2702 }
2703 
2704 ////////////////////////////////////////////////////////////////////////////////
2705 /// Unload a shared library.
2706 
2707 void TUnixSystem::Unload(const char *module)
2708 {
2709  if (module) { TSystem::Unload(module); }
2710 }
2711 
2712 ////////////////////////////////////////////////////////////////////////////////
2713 /// List symbols in a shared library.
2714 
2715 void TUnixSystem::ListSymbols(const char * /*module*/, const char * /*regexp*/)
2716 {
2717  Error("ListSymbols", "not yet implemented");
2718 }
2719 
2720 ////////////////////////////////////////////////////////////////////////////////
2721 /// List all loaded shared libraries.
2722 
2723 void TUnixSystem::ListLibraries(const char *regexp)
2724 {
2725  TSystem::ListLibraries(regexp);
2726 }
2727 
2728 ////////////////////////////////////////////////////////////////////////////////
2729 /// Get list of shared libraries loaded at the start of the executable.
2730 /// Returns 0 in case list cannot be obtained or in case of error.
2731 
2733 {
2734  static TString linkedLibs;
2735  static Bool_t once = kFALSE;
2736 
2738 
2739  if (!linkedLibs.IsNull())
2740  return linkedLibs;
2741 
2742  if (once)
2743  return 0;
2744 
2745 #if !defined(R__MACOSX)
2746  const char *exe = GetExePath();
2747  if (!exe || !*exe)
2748  return 0;
2749 #endif
2750 
2751 #if defined(R__MACOSX)
2752  DylibAdded(0, 0);
2753  linkedLibs = gLinkedDylibs;
2754 #if 0
2755  FILE *p = OpenPipe(TString::Format("otool -L %s", exe), "r");
2756  TString otool;
2757  while (otool.Gets(p)) {
2758  TString delim(" \t");
2759  TObjArray *tok = otool.Tokenize(delim);
2760  TString dylib = ((TObjString*)tok->At(0))->String();
2761  if (dylib.EndsWith(".dylib") && !dylib.Contains("/libSystem.B.dylib")) {
2762  if (!linkedLibs.IsNull())
2763  linkedLibs += " ";
2764  linkedLibs += dylib;
2765  }
2766  delete tok;
2767  }
2768  if (p) {
2769  ClosePipe(p);
2770  }
2771 #endif
2772 #elif defined(R__LINUX) || defined(R__SOLARIS) || defined(R__AIX)
2773 #if defined(R__WINGCC )
2774  const char *cLDD="cygcheck";
2775  const char *cSOEXT=".dll";
2776  size_t lenexe = strlen(exe);
2777  if (strcmp(exe + lenexe - 4, ".exe")
2778  && strcmp(exe + lenexe - 4, ".dll")) {
2779  // it's not a dll and exe doesn't end on ".exe";
2780  // need to add it for cygcheck to find it:
2781  char* longerexe = new char[lenexe + 5];
2782  strlcpy(longerexe, exe,lenexe+5);
2783  strlcat(longerexe, ".exe",lenexe+5);
2784  delete [] exe;
2785  exe = longerexe;
2786  }
2787  TRegexp sovers = "\\.so\\.[0-9]+";
2788 #else
2789  const char *cLDD="ldd";
2790 #if defined(R__AIX)
2791  const char *cSOEXT=".a";
2792  TRegexp sovers = "\\.a\\.[0-9]+";
2793 #else
2794  const char *cSOEXT=".so";
2795  TRegexp sovers = "\\.so\\.[0-9]+";
2796 #endif
2797 #endif
2798  FILE *p = OpenPipe(TString::Format("%s '%s'", cLDD, exe), "r");
2799  if (p) {
2800  TString ldd;
2801  while (ldd.Gets(p)) {
2802  TString delim(" \t");
2803  TObjArray *tok = ldd.Tokenize(delim);
2804 
2805  // expected format:
2806  // libCore.so => /home/rdm/root/lib/libCore.so (0x40017000)
2807  TObjString *solibName = (TObjString*)tok->At(2);
2808  if (!solibName) {
2809  // case where there is only one name of the list:
2810  // /usr/platform/SUNW,UltraAX-i2/lib/libc_psr.so.1
2811  solibName = (TObjString*)tok->At(0);
2812  }
2813  if (solibName) {
2814  TString solib = solibName->String();
2815  Ssiz_t idx = solib.Index(sovers);
2816  if (solib.EndsWith(cSOEXT) || idx != kNPOS) {
2817  if (idx != kNPOS)
2818  solib.Remove(idx+3);
2819  if (!AccessPathName(solib, kReadPermission)) {
2820  if (!linkedLibs.IsNull())
2821  linkedLibs += " ";
2822  linkedLibs += solib;
2823  }
2824  }
2825  }
2826  delete tok;
2827  }
2828  ClosePipe(p);
2829  }
2830 #endif
2831 
2832  once = kTRUE;
2833 
2834  if (linkedLibs.IsNull())
2835  return 0;
2836 
2837  return linkedLibs;
2838 }
2839 
2840 //---- Time & Date -------------------------------------------------------------
2841 
2842 ////////////////////////////////////////////////////////////////////////////////
2843 /// Get current time in milliseconds since 0:00 Jan 1 1995.
2844 
2846 {
2847  return UnixNow();
2848 }
2849 
2850 ////////////////////////////////////////////////////////////////////////////////
2851 /// Handle and dispatch timers. If mode = kTRUE dispatch synchronous
2852 /// timers else a-synchronous timers.
2853 
2855 {
2856  if (!fTimers) return kFALSE;
2857 
2858  fInsideNotify = kTRUE;
2859 
2861  TTimer *t;
2862  Bool_t timedout = kFALSE;
2863 
2864  while ((t = (TTimer *) it.Next())) {
2865  // NB: the timer resolution is added in TTimer::CheckTimer()
2866  Long64_t now = UnixNow();
2867  if (mode && t->IsSync()) {
2868  if (t->CheckTimer(now))
2869  timedout = kTRUE;
2870  } else if (!mode && t->IsAsync()) {
2871  if (t->CheckTimer(now)) {
2873  timedout = kTRUE;
2874  }
2875  }
2876  }
2878  return timedout;
2879 }
2880 
2881 ////////////////////////////////////////////////////////////////////////////////
2882 /// Add timer to list of system timers.
2883 
2885 {
2886  TSystem::AddTimer(ti);
2887  ResetTimer(ti);
2888 }
2889 
2890 ////////////////////////////////////////////////////////////////////////////////
2891 /// Remove timer from list of system timers.
2892 
2894 {
2895  if (!ti) return 0;
2896 
2898 
2899  TTimer *t = TSystem::RemoveTimer(ti);
2900  if (ti->IsAsync())
2902  return t;
2903 }
2904 
2905 ////////////////////////////////////////////////////////////////////////////////
2906 /// Reset a-sync timer.
2907 
2909 {
2910  if (!fInsideNotify && ti && ti->IsAsync())
2912 }
2913 
2914 //---- RPC ---------------------------------------------------------------------
2915 
2916 ////////////////////////////////////////////////////////////////////////////////
2917 /// Get Internet Protocol (IP) address of host. Returns an TInetAddress
2918 /// object. To see if the hostname lookup was successfull call
2919 /// TInetAddress::IsValid().
2920 
2922 {
2923  struct hostent *host_ptr;
2924  const char *host;
2925  int type;
2926  UInt_t addr; // good for 4 byte addresses
2927 
2928  // Note that http://linux.die.net/man/3/gethostbyaddr
2929  // claims:
2930  // The gethostbyname*() and gethostbyaddr*() functions are obsolete.
2931  // Applications should use getaddrinfo(3) and getnameinfo(3) instead.
2932 
2933  // gethostbyaddr return the address of static data, we need to insure
2934  // exclusive access ... the 'right' solution is to switch to getaddrinfo
2935 
2937 
2938 #ifdef HASNOT_INETATON
2939  if ((addr = (UInt_t)inet_addr(hostname)) != INADDR_NONE) {
2940 #else
2941  struct in_addr ad;
2942  if (inet_aton(hostname, &ad)) {
2943  memcpy(&addr, &ad.s_addr, sizeof(ad.s_addr));
2944 #endif
2945  type = AF_INET;
2946  if ((host_ptr = gethostbyaddr((const char *)&addr,
2947  sizeof(addr), AF_INET))) {
2948  host = host_ptr->h_name;
2949  TInetAddress a(host, ntohl(addr), type);
2950  UInt_t addr2;
2951  Int_t i;
2952  for (i = 1; host_ptr->h_addr_list[i]; i++) {
2953  memcpy(&addr2, host_ptr->h_addr_list[i], host_ptr->h_length);
2954  a.AddAddress(ntohl(addr2));
2955  }
2956  for (i = 0; host_ptr->h_aliases[i]; i++)
2957  a.AddAlias(host_ptr->h_aliases[i]);
2958  return a;
2959  } else {
2960  host = "UnNamedHost";
2961  }
2962  } else if ((host_ptr = gethostbyname(hostname))) {
2963  // Check the address type for an internet host
2964  if (host_ptr->h_addrtype != AF_INET) {
2965  Error("GetHostByName", "%s is not an internet host\n", hostname);
2966  return TInetAddress();
2967  }
2968  memcpy(&addr, host_ptr->h_addr, host_ptr->h_length);
2969  host = host_ptr->h_name;
2970  type = host_ptr->h_addrtype;
2971  TInetAddress a(host, ntohl(addr), type);
2972  UInt_t addr2;
2973  Int_t i;
2974  for (i = 1; host_ptr->h_addr_list[i]; i++) {
2975  memcpy(&addr2, host_ptr->h_addr_list[i], host_ptr->h_length);
2976  a.AddAddress(ntohl(addr2));
2977  }
2978  for (i = 0; host_ptr->h_aliases[i]; i++)
2979  a.AddAlias(host_ptr->h_aliases[i]);
2980  return a;
2981  } else {
2982  if (gDebug > 0) Error("GetHostByName", "unknown host %s", hostname);
2983  return TInetAddress(hostname, 0, -1);
2984  }
2985 
2986  return TInetAddress(host, ntohl(addr), type);
2987 }
2988 
2989 ////////////////////////////////////////////////////////////////////////////////
2990 /// Get Internet Protocol (IP) address of host and port #.
2991 
2993 {
2994  struct sockaddr_in addr;
2995 #if defined(USE_SIZE_T)
2996  size_t len = sizeof(addr);
2997 #elif defined(USE_SOCKLEN_T)
2998  socklen_t len = sizeof(addr);
2999 #else
3000  int len = sizeof(addr);
3001 #endif
3002 
3003  if (getsockname(sock, (struct sockaddr *)&addr, &len) == -1) {
3004  SysError("GetSockName", "getsockname");
3005  return TInetAddress();
3006  }
3007 
3008  struct hostent *host_ptr;
3009  const char *hostname;
3010  int family;
3011  UInt_t iaddr;
3012 
3013  if ((host_ptr = gethostbyaddr((const char *)&addr.sin_addr,
3014  sizeof(addr.sin_addr), AF_INET))) {
3015  memcpy(&iaddr, host_ptr->h_addr, host_ptr->h_length);
3016  hostname = host_ptr->h_name;
3017  family = host_ptr->h_addrtype;
3018  } else {
3019  memcpy(&iaddr, &addr.sin_addr, sizeof(addr.sin_addr));
3020  hostname = "????";
3021  family = AF_INET;
3022  }
3023 
3024  return TInetAddress(hostname, ntohl(iaddr), family, ntohs(addr.sin_port));
3025 }
3026 
3027 ////////////////////////////////////////////////////////////////////////////////
3028 /// Get Internet Protocol (IP) address of remote host and port #.
3029 
3031 {
3032  struct sockaddr_in addr;
3033 #if defined(USE_SIZE_T)
3034  size_t len = sizeof(addr);
3035 #elif defined(USE_SOCKLEN_T)
3036  socklen_t len = sizeof(addr);
3037 #else
3038  int len = sizeof(addr);
3039 #endif
3040 
3041  if (getpeername(sock, (struct sockaddr *)&addr, &len) == -1) {
3042  SysError("GetPeerName", "getpeername");
3043  return TInetAddress();
3044  }
3045 
3046  struct hostent *host_ptr;
3047  const char *hostname;
3048  int family;
3049  UInt_t iaddr;
3050 
3051  if ((host_ptr = gethostbyaddr((const char *)&addr.sin_addr,
3052  sizeof(addr.sin_addr), AF_INET))) {
3053  memcpy(&iaddr, host_ptr->h_addr, host_ptr->h_length);
3054  hostname = host_ptr->h_name;
3055  family = host_ptr->h_addrtype;
3056  } else {
3057  memcpy(&iaddr, &addr.sin_addr, sizeof(addr.sin_addr));
3058  hostname = "????";
3059  family = AF_INET;
3060  }
3061 
3062  return TInetAddress(hostname, ntohl(iaddr), family, ntohs(addr.sin_port));
3063 }
3064 
3065 ////////////////////////////////////////////////////////////////////////////////
3066 /// Get port # of internet service.
3067 
3068 int TUnixSystem::GetServiceByName(const char *servicename)
3069 {
3070  struct servent *sp;
3071 
3072  if ((sp = getservbyname(servicename, kProtocolName)) == 0) {
3073  Error("GetServiceByName", "no service \"%s\" with protocol \"%s\"\n",
3074  servicename, kProtocolName);
3075  return -1;
3076  }
3077  return ntohs(sp->s_port);
3078 }
3079 
3080 ////////////////////////////////////////////////////////////////////////////////
3081 /// Get name of internet service.
3082 
3084 {
3085  struct servent *sp;
3086 
3087  if ((sp = getservbyport(htons(port), kProtocolName)) == 0) {
3088  //::Error("GetServiceByPort", "no service \"%d\" with protocol \"%s\"",
3089  // port, kProtocolName);
3090  return Form("%d", port);
3091  }
3092  return sp->s_name;
3093 }
3094 
3095 ////////////////////////////////////////////////////////////////////////////////
3096 /// Connect to service servicename on server servername.
3097 
3098 int TUnixSystem::ConnectService(const char *servername, int port,
3099  int tcpwindowsize, const char *protocol)
3100 {
3101  if (!strcmp(servername, "unix")) {
3102  return UnixUnixConnect(port);
3103  } else if (!gSystem->AccessPathName(servername) || servername[0] == '/') {
3104  return UnixUnixConnect(servername);
3105  }
3106 
3107  if (!strcmp(protocol, "udp")){
3108  return UnixUdpConnect(servername, port);
3109  }
3110 
3111  return UnixTcpConnect(servername, port, tcpwindowsize);
3112 }
3113 
3114 ////////////////////////////////////////////////////////////////////////////////
3115 /// Open a connection to a service on a server. Returns -1 in case
3116 /// connection cannot be opened.
3117 /// Use tcpwindowsize to specify the size of the receive buffer, it has
3118 /// to be specified here to make sure the window scale option is set (for
3119 /// tcpwindowsize > 65KB and for platforms supporting window scaling).
3120 /// Is called via the TSocket constructor.
3121 
3122 int TUnixSystem::OpenConnection(const char *server, int port, int tcpwindowsize, const char *protocol)
3123 {
3124  return ConnectService(server, port, tcpwindowsize, protocol);
3125 }
3126 
3127 ////////////////////////////////////////////////////////////////////////////////
3128 /// Announce TCP/IP service.
3129 /// Open a socket, bind to it and start listening for TCP/IP connections
3130 /// on the port. If reuse is true reuse the address, backlog specifies
3131 /// how many sockets can be waiting to be accepted.
3132 /// Use tcpwindowsize to specify the size of the receive buffer, it has
3133 /// to be specified here to make sure the window scale option is set (for
3134 /// tcpwindowsize > 65KB and for platforms supporting window scaling).
3135 /// Returns socket fd or -1 if socket() failed, -2 if bind() failed
3136 /// or -3 if listen() failed.
3137 
3138 int TUnixSystem::AnnounceTcpService(int port, Bool_t reuse, int backlog,
3139  int tcpwindowsize)
3140 {
3141  return UnixTcpService(port, reuse, backlog, tcpwindowsize);
3142 }
3143 
3144 ////////////////////////////////////////////////////////////////////////////////
3145 /// Announce UDP service.
3146 
3147 int TUnixSystem::AnnounceUdpService(int port, int backlog)
3148 {
3149  return UnixUdpService(port, backlog);
3150 }
3151 
3152 ////////////////////////////////////////////////////////////////////////////////
3153 /// Announce unix domain service on path "kServerPath/<port>"
3154 
3155 int TUnixSystem::AnnounceUnixService(int port, int backlog)
3156 {
3157  return UnixUnixService(port, backlog);
3158 }
3159 
3160 ////////////////////////////////////////////////////////////////////////////////
3161 /// Announce unix domain service on path 'sockpath'
3162 
3163 int TUnixSystem::AnnounceUnixService(const char *sockpath, int backlog)
3164 {
3165  return UnixUnixService(sockpath, backlog);
3166 }
3167 
3168 ////////////////////////////////////////////////////////////////////////////////
3169 /// Accept a connection. In case of an error return -1. In case
3170 /// non-blocking I/O is enabled and no connections are available
3171 /// return -2.
3172 
3174 {
3175  int soc = -1;
3176 
3177  while ((soc = ::accept(sock, 0, 0)) == -1 && GetErrno() == EINTR)
3178  ResetErrno();
3179 
3180  if (soc == -1) {
3181  if (GetErrno() == EWOULDBLOCK)
3182  return -2;
3183  else {
3184  SysError("AcceptConnection", "accept");
3185  return -1;
3186  }
3187  }
3188 
3189  return soc;
3190 }
3191 
3192 ////////////////////////////////////////////////////////////////////////////////
3193 /// Close socket.
3194 
3196 {
3197  if (sock < 0) return;
3198 
3199 #if !defined(R__AIX) || defined(_AIX41) || defined(_AIX43)
3200  if (force)
3201  ::shutdown(sock, 2); // will also close connection of parent
3202 #endif
3203 
3204  while (::close(sock) == -1 && GetErrno() == EINTR)
3205  ResetErrno();
3206 }
3207 
3208 ////////////////////////////////////////////////////////////////////////////////
3209 /// Receive a buffer headed by a length indicator. Length is the size of
3210 /// the buffer. Returns the number of bytes received in buf or -1 in
3211 /// case of error.
3212 
3213 int TUnixSystem::RecvBuf(int sock, void *buf, int length)
3214 {
3215  Int_t header;
3216 
3217  if (UnixRecv(sock, &header, sizeof(header), 0) > 0) {
3218  int count = ntohl(header);
3219 
3220  if (count > length) {
3221  Error("RecvBuf", "record header exceeds buffer size");
3222  return -1;
3223  } else if (count > 0) {
3224  if (UnixRecv(sock, buf, count, 0) < 0) {
3225  Error("RecvBuf", "cannot receive buffer");
3226  return -1;
3227  }
3228  }
3229  return count;
3230  }
3231  return -1;
3232 }
3233 
3234 ////////////////////////////////////////////////////////////////////////////////
3235 /// Send a buffer headed by a length indicator. Returns length of sent buffer
3236 /// or -1 in case of error.
3237 
3238 int TUnixSystem::SendBuf(int sock, const void *buf, int length)
3239 {
3240  Int_t header = htonl(length);
3241 
3242  if (UnixSend(sock, &header, sizeof(header), 0) < 0) {
3243  Error("SendBuf", "cannot send header");
3244  return -1;
3245  }
3246  if (length > 0) {
3247  if (UnixSend(sock, buf, length, 0) < 0) {
3248  Error("SendBuf", "cannot send buffer");
3249  return -1;
3250  }
3251  }
3252  return length;
3253 }
3254 
3255 ////////////////////////////////////////////////////////////////////////////////
3256 /// Receive exactly length bytes into buffer. Use opt to receive out-of-band
3257 /// data or to have a peek at what is in the buffer (see TSocket). Buffer
3258 /// must be able to store at least length bytes. Returns the number of
3259 /// bytes received (can be 0 if other side of connection was closed) or -1
3260 /// in case of error, -2 in case of MSG_OOB and errno == EWOULDBLOCK, -3
3261 /// in case of MSG_OOB and errno == EINVAL and -4 in case of kNoBlock and
3262 /// errno == EWOULDBLOCK. Returns -5 if pipe broken or reset by peer
3263 /// (EPIPE || ECONNRESET).
3264 
3265 int TUnixSystem::RecvRaw(int sock, void *buf, int length, int opt)
3266 {
3267  int flag;
3268 
3269  switch (opt) {
3270  case kDefault:
3271  flag = 0;
3272  break;
3273  case kOob:
3274  flag = MSG_OOB;
3275  break;
3276  case kPeek:
3277  flag = MSG_PEEK;
3278  break;
3279  case kDontBlock:
3280  flag = -1;
3281  break;
3282  default:
3283  flag = 0;
3284  break;
3285  }
3286 
3287  int n;
3288  if ((n = UnixRecv(sock, buf, length, flag)) <= 0) {
3289  if (n == -1 && GetErrno() != EINTR)
3290  Error("RecvRaw", "cannot receive buffer");
3291  return n;
3292  }
3293  return n;
3294 }
3295 
3296 ////////////////////////////////////////////////////////////////////////////////
3297 /// Send exactly length bytes from buffer. Use opt to send out-of-band
3298 /// data (see TSocket). Returns the number of bytes sent or -1 in case of
3299 /// error. Returns -4 in case of kNoBlock and errno == EWOULDBLOCK.
3300 /// Returns -5 if pipe broken or reset by peer (EPIPE || ECONNRESET).
3301 
3302 int TUnixSystem::SendRaw(int sock, const void *buf, int length, int opt)
3303 {
3304  int flag;
3305 
3306  switch (opt) {
3307  case kDefault:
3308  flag = 0;
3309  break;
3310  case kOob:
3311  flag = MSG_OOB;
3312  break;
3313  case kDontBlock:
3314  flag = -1;
3315  break;
3316  case kPeek: // receive only option (see RecvRaw)
3317  default:
3318  flag = 0;
3319  break;
3320  }
3321 
3322  int n;
3323  if ((n = UnixSend(sock, buf, length, flag)) <= 0) {
3324  if (n == -1 && GetErrno() != EINTR)
3325  Error("SendRaw", "cannot send buffer");
3326  return n;
3327  }
3328  return n;
3329 }
3330 
3331 ////////////////////////////////////////////////////////////////////////////////
3332 /// Set socket option.
3333 
3334 int TUnixSystem::SetSockOpt(int sock, int opt, int val)
3335 {
3336  if (sock < 0) return -1;
3337 
3338  switch (opt) {
3339  case kSendBuffer:
3340  if (setsockopt(sock, SOL_SOCKET, SO_SNDBUF, (char*)&val, sizeof(val)) == -1) {
3341  SysError("SetSockOpt", "setsockopt(SO_SNDBUF)");
3342  return -1;
3343  }
3344  break;
3345  case kRecvBuffer:
3346  if (setsockopt(sock, SOL_SOCKET, SO_RCVBUF, (char*)&val, sizeof(val)) == -1) {
3347  SysError("SetSockOpt", "setsockopt(SO_RCVBUF)");
3348  return -1;
3349  }
3350  break;
3351  case kOobInline:
3352  if (setsockopt(sock, SOL_SOCKET, SO_OOBINLINE, (char*)&val, sizeof(val)) == -1) {
3353  SysError("SetSockOpt", "setsockopt(SO_OOBINLINE)");
3354  return -1;
3355  }
3356  break;
3357  case kKeepAlive:
3358  if (setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, (char*)&val, sizeof(val)) == -1) {
3359  SysError("SetSockOpt", "setsockopt(SO_KEEPALIVE)");
3360  return -1;
3361  }
3362  break;
3363  case kReuseAddr:
3364  if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char*)&val, sizeof(val)) == -1) {
3365  SysError("SetSockOpt", "setsockopt(SO_REUSEADDR)");
3366  return -1;
3367  }
3368  break;
3369  case kNoDelay:
3370  if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (char*)&val, sizeof(val)) == -1) {
3371  SysError("SetSockOpt", "setsockopt(TCP_NODELAY)");
3372  return -1;
3373  }
3374  break;
3375  case kNoBlock:
3376  if (ioctl(sock, FIONBIO, (char*)&val) == -1) {
3377  SysError("SetSockOpt", "ioctl(FIONBIO)");
3378  return -1;
3379  }
3380  break;
3381  case kProcessGroup:
3382 #ifndef R__WINGCC
3383  if (ioctl(sock, SIOCSPGRP, (char*)&val) == -1) {
3384  SysError("SetSockOpt", "ioctl(SIOCSPGRP)");
3385  return -1;
3386  }
3387 #else
3388  Error("SetSockOpt", "ioctl(SIOCGPGRP) not supported on cygwin/gcc");
3389  return -1;
3390 #endif
3391  break;
3392  case kAtMark: // read-only option (see GetSockOpt)
3393  case kBytesToRead: // read-only option
3394  default:
3395  Error("SetSockOpt", "illegal option (%d)", opt);
3396  return -1;
3397  }
3398  return 0;
3399 }
3400 
3401 ////////////////////////////////////////////////////////////////////////////////
3402 /// Get socket option.
3403 
3404 int TUnixSystem::GetSockOpt(int sock, int opt, int *val)
3405 {
3406  if (sock < 0) return -1;
3407 
3408 #if defined(USE_SOCKLEN_T) || defined(_AIX43)
3409  socklen_t optlen = sizeof(*val);
3410 #elif defined(USE_SIZE_T)
3411  size_t optlen = sizeof(*val);
3412 #else
3413  int optlen = sizeof(*val);
3414 #endif
3415 
3416  switch (opt) {
3417  case kSendBuffer:
3418  if (getsockopt(sock, SOL_SOCKET, SO_SNDBUF, (char*)val, &optlen) == -1) {
3419  SysError("GetSockOpt", "getsockopt(SO_SNDBUF)");
3420  return -1;
3421  }
3422  break;
3423  case kRecvBuffer:
3424  if (getsockopt(sock, SOL_SOCKET, SO_RCVBUF, (char*)val, &optlen) == -1) {
3425  SysError("GetSockOpt", "getsockopt(SO_RCVBUF)");
3426  return -1;
3427  }
3428  break;
3429  case kOobInline:
3430  if (getsockopt(sock, SOL_SOCKET, SO_OOBINLINE, (char*)val, &optlen) == -1) {
3431  SysError("GetSockOpt", "getsockopt(SO_OOBINLINE)");
3432  return -1;
3433  }
3434  break;
3435  case kKeepAlive:
3436  if (getsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, (char*)val, &optlen) == -1) {
3437  SysError("GetSockOpt", "getsockopt(SO_KEEPALIVE)");
3438  return -1;
3439  }
3440  break;
3441  case kReuseAddr:
3442  if (getsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char*)val, &optlen) == -1) {
3443  SysError("GetSockOpt", "getsockopt(SO_REUSEADDR)");
3444  return -1;
3445  }
3446  break;
3447  case kNoDelay:
3448  if (getsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (char*)val, &optlen) == -1) {
3449  SysError("GetSockOpt", "getsockopt(TCP_NODELAY)");
3450  return -1;
3451  }
3452  break;
3453  case kNoBlock:
3454  int flg;
3455  if ((flg = fcntl(sock, F_GETFL, 0)) == -1) {
3456  SysError("GetSockOpt", "fcntl(F_GETFL)");
3457  return -1;
3458  }
3459  *val = flg & O_NDELAY;
3460  break;
3461  case kProcessGroup:
3462 #if !defined(R__LYNXOS) && !defined(R__WINGCC)
3463  if (ioctl(sock, SIOCGPGRP, (char*)val) == -1) {
3464  SysError("GetSockOpt", "ioctl(SIOCGPGRP)");
3465  return -1;
3466  }
3467 #else
3468  Error("GetSockOpt", "ioctl(SIOCGPGRP) not supported on LynxOS and cygwin/gcc");
3469  return -1;
3470 #endif
3471  break;
3472  case kAtMark:
3473 #if !defined(R__LYNXOS)
3474  if (ioctl(sock, SIOCATMARK, (char*)val) == -1) {
3475  SysError("GetSockOpt", "ioctl(SIOCATMARK)");
3476  return -1;
3477  }
3478 #else
3479  Error("GetSockOpt", "ioctl(SIOCATMARK) not supported on LynxOS");
3480  return -1;
3481 #endif
3482  break;
3483  case kBytesToRead:
3484 #if !defined(R__LYNXOS)
3485  if (ioctl(sock, FIONREAD, (char*)val) == -1) {
3486  SysError("GetSockOpt", "ioctl(FIONREAD)");
3487  return -1;
3488  }
3489 #else
3490  Error("GetSockOpt", "ioctl(FIONREAD) not supported on LynxOS");
3491  return -1;
3492 #endif
3493  break;
3494  default:
3495  Error("GetSockOpt", "illegal option (%d)", opt);
3496  *val = 0;
3497  return -1;
3498  }
3499  return 0;
3500 }
3501 
3502 //////////////////////////////////////////////////////////////////////////
3503 // //
3504 // Static Protected Unix Interface functions. //
3505 // //
3506 //////////////////////////////////////////////////////////////////////////
3507 
3508 //---- signals -----------------------------------------------------------------
3509 
3510 static struct Signalmap_t {
3511  int fCode;
3512  SigHandler_t fHandler;
3513  struct sigaction *fOldHandler;
3514  const char *fSigName;
3515 } gSignalMap[kMAXSIGNALS] = { // the order of the signals should be identical
3516  { SIGBUS, 0, 0, "bus error" }, // to the one in TSysEvtHandler.h
3517  { SIGSEGV, 0, 0, "segmentation violation" },
3518  { SIGSYS, 0, 0, "bad argument to system call" },
3519  { SIGPIPE, 0, 0, "write on a pipe with no one to read it" },
3520  { SIGILL, 0, 0, "illegal instruction" },
3521  { SIGQUIT, 0, 0, "quit" },
3522  { SIGINT, 0, 0, "interrupt" },
3523  { SIGWINCH, 0, 0, "window size change" },
3524  { SIGALRM, 0, 0, "alarm clock" },
3525  { SIGCHLD, 0, 0, "death of a child" },
3526  { SIGURG, 0, 0, "urgent data arrived on an I/O channel" },
3527  { SIGFPE, 0, 0, "floating point exception" },
3528  { SIGTERM, 0, 0, "termination signal" },
3529  { SIGUSR1, 0, 0, "user-defined signal 1" },
3530  { SIGUSR2, 0, 0, "user-defined signal 2" }
3531 };
3532 
3533 
3534 ////////////////////////////////////////////////////////////////////////////////
3535 /// Call the signal handler associated with the signal.
3536 
3537 static void sighandler(int sig)
3538 {
3539  for (int i= 0; i < kMAXSIGNALS; i++) {
3540  if (gSignalMap[i].fCode == sig) {
3541  (*gSignalMap[i].fHandler)((ESignals)i);
3542  return;
3543  }
3544  }
3545 }
3546 
3547 ////////////////////////////////////////////////////////////////////////////////
3548 /// Handle and dispatch signals.
3549 
3551 {
3552  switch (sig) {
3553  case kSigAlarm:
3555  break;
3556  case kSigChild:
3557  CheckChilds();
3558  break;
3559  case kSigBus:
3562  case kSigFloatingException:
3563  Break("TUnixSystem::DispatchSignals", "%s", UnixSigname(sig));
3564  StackTrace();
3565  if (gApplication)
3566  //sig is ESignal, should it be mapped to the correct signal number?
3568  else
3569  //map to the real signal code + set the
3570  //high order bit to indicate a signal (?)
3571  Exit(gSignalMap[sig].fCode + 0x80);
3572  break;
3573  case kSigSystem:
3574  case kSigPipe:
3575  Break("TUnixSystem::DispatchSignals", "%s", UnixSigname(sig));
3576  break;
3577  case kSigWindowChanged:
3578  Gl_windowchanged();
3579  break;
3580  default:
3581  fSignals->Set(sig);
3582  fSigcnt++;
3583  break;
3584  }
3585 
3586  // check a-synchronous signals
3587  if (fSigcnt > 0 && fSignalHandler->GetSize() > 0)
3589 }
3590 
3591 ////////////////////////////////////////////////////////////////////////////////
3592 /// Set a signal handler for a signal.
3593 
3595 {
3596  if (gEnv && !gEnv->GetValue("Root.ErrorHandlers", 1))
3597  return;
3598 
3599  if (gSignalMap[sig].fHandler != handler) {
3600  struct sigaction sigact;
3601 
3602  gSignalMap[sig].fHandler = handler;
3603  gSignalMap[sig].fOldHandler = new struct sigaction();
3604 
3605 #if defined(R__SUN)
3606  sigact.sa_handler = (void (*)())sighandler;
3607 #elif defined(R__SOLARIS)
3608  sigact.sa_handler = sighandler;
3609 #elif defined(R__LYNXOS)
3610 # if (__GNUG__>=3)
3611  sigact.sa_handler = sighandler;
3612 # else
3613  sigact.sa_handler = (void (*)(...))sighandler;
3614 # endif
3615 #else
3616  sigact.sa_handler = sighandler;
3617 #endif
3618  sigemptyset(&sigact.sa_mask);
3619  sigact.sa_flags = 0;
3620 #if defined(SA_RESTART)
3621  sigact.sa_flags |= SA_RESTART;
3622 #endif
3623  if (sigaction(gSignalMap[sig].fCode, &sigact,
3624  gSignalMap[sig].fOldHandler) < 0)
3625  ::SysError("TUnixSystem::UnixSignal", "sigaction");
3626  }
3627 }
3628 
3629 ////////////////////////////////////////////////////////////////////////////////
3630 /// If ignore is true ignore the specified signal, else restore previous
3631 /// behaviour.
3632 
3634 {
3635  TTHREAD_TLS(Bool_t) ignoreSig[kMAXSIGNALS] = { kFALSE };
3636  TTHREAD_TLS_ARRAY(struct sigaction,kMAXSIGNALS,oldsigact);
3637 
3638  if (ignore != ignoreSig[sig]) {
3639  ignoreSig[sig] = ignore;
3640  if (ignore) {
3641  struct sigaction sigact;
3642 #if defined(R__SUN)
3643  sigact.sa_handler = (void (*)())SIG_IGN;
3644 #elif defined(R__SOLARIS)
3645  sigact.sa_handler = (void (*)(int))SIG_IGN;
3646 #else
3647  sigact.sa_handler = SIG_IGN;
3648 #endif
3649  sigemptyset(&sigact.sa_mask);
3650  sigact.sa_flags = 0;
3651  if (sigaction(gSignalMap[sig].fCode, &sigact, &oldsigact[sig]) < 0)
3652  ::SysError("TUnixSystem::UnixIgnoreSignal", "sigaction");
3653  } else {
3654  if (sigaction(gSignalMap[sig].fCode, &oldsigact[sig], 0) < 0)
3655  ::SysError("TUnixSystem::UnixIgnoreSignal", "sigaction");
3656  }
3657  }
3658 }
3659 
3660 ////////////////////////////////////////////////////////////////////////////////
3661 /// When the argument is true the SIGALRM signal handler is set so that
3662 /// interrupted syscalls will not be restarted by the kernel. This is
3663 /// typically used in case one wants to put a timeout on an I/O operation.
3664 /// By default interrupted syscalls will always be restarted (for all
3665 /// signals). This can be controlled for each a-synchronous TTimer via
3666 /// the method TTimer::SetInterruptSyscalls().
3667 
3669 {
3670  if (gSignalMap[kSigAlarm].fHandler) {
3671  struct sigaction sigact;
3672 #if defined(R__SUN)
3673  sigact.sa_handler = (void (*)())sighandler;
3674 #elif defined(R__SOLARIS)
3675  sigact.sa_handler = sighandler;
3676 #elif defined(R__LYNXOS)
3677 # if (__GNUG__>=3)
3678  sigact.sa_handler = sighandler;
3679 # else
3680  sigact.sa_handler = (void (*)(...))sighandler;
3681 # endif
3682 #else
3683  sigact.sa_handler = sighandler;
3684 #endif
3685  sigemptyset(&sigact.sa_mask);
3686  sigact.sa_flags = 0;
3687  if (set) {
3688 #if defined(SA_INTERRUPT) // SunOS
3689  sigact.sa_flags |= SA_INTERRUPT;
3690 #endif
3691  } else {
3692 #if defined(SA_RESTART)
3693  sigact.sa_flags |= SA_RESTART;
3694 #endif
3695  }
3696  if (sigaction(gSignalMap[kSigAlarm].fCode, &sigact, 0) < 0)
3697  ::SysError("TUnixSystem::UnixSigAlarmInterruptsSyscalls", "sigaction");
3698  }
3699 }
3700 
3701 ////////////////////////////////////////////////////////////////////////////////
3702 /// Return the signal name associated with a signal.
3703 
3705 {
3706  return gSignalMap[sig].fSigName;
3707 }
3708 
3709 ////////////////////////////////////////////////////////////////////////////////
3710 /// Restore old signal handler for specified signal.
3711 
3713 {
3714  if (gSignalMap[sig].fOldHandler) {
3715  // restore old signal handler
3716  if (sigaction(gSignalMap[sig].fCode, gSignalMap[sig].fOldHandler, 0) < 0)
3717  ::SysError("TUnixSystem::UnixSignal", "sigaction");
3718  delete gSignalMap[sig].fOldHandler;
3719  gSignalMap[sig].fOldHandler = 0;
3720  gSignalMap[sig].fHandler = 0;
3721  }
3722 }
3723 
3724 ////////////////////////////////////////////////////////////////////////////////
3725 /// Restore old signal handlers.
3726 
3728 {
3729  for (int sig = 0; sig < kMAXSIGNALS; sig++)
3730  UnixResetSignal((ESignals)sig);
3731 }
3732 
3733 //---- time --------------------------------------------------------------------
3734 
3735 ////////////////////////////////////////////////////////////////////////////////
3736 /// Get current time in milliseconds since 0:00 Jan 1 1995.
3737 
3739 {
3740  static std::atomic<time_t> jan95{0};
3741  if (!jan95) {
3742  struct tm tp;
3743  tp.tm_year = 95;
3744  tp.tm_mon = 0;
3745  tp.tm_mday = 1;
3746  tp.tm_hour = 0;
3747  tp.tm_min = 0;
3748  tp.tm_sec = 0;
3749  tp.tm_isdst = -1;
3750 
3751  jan95 = mktime(&tp);
3752  if ((int)jan95 == -1) {
3753  ::SysError("TUnixSystem::UnixNow", "error converting 950001 0:00 to time_t");
3754  return 0;
3755  }
3756  }
3757 
3758  struct timeval t;
3759  gettimeofday(&t, 0);
3760  return Long64_t(t.tv_sec-(Long_t)jan95)*1000 + t.tv_usec/1000;
3761 }
3762 
3763 ////////////////////////////////////////////////////////////////////////////////
3764 /// Set interval timer to time-out in ms milliseconds.
3765 
3767 {
3768  struct itimerval itv;
3769  itv.it_value.tv_sec = 0;
3770  itv.it_value.tv_usec = 0;
3771  itv.it_interval.tv_sec = 0;
3772  itv.it_interval.tv_usec = 0;
3773  if (ms > 0) {
3774  itv.it_value.tv_sec = time_t(ms / 1000);
3775  itv.it_value.tv_usec = time_t((ms % 1000) * 1000);
3776  }
3777  int st = setitimer(ITIMER_REAL, &itv, 0);
3778  if (st == -1)
3779  ::SysError("TUnixSystem::UnixSetitimer", "setitimer");
3780  return st;
3781 }
3782 
3783 //---- file descriptors --------------------------------------------------------
3784 
3785 ////////////////////////////////////////////////////////////////////////////////
3786 /// Wait for events on the file descriptors specified in the readready and
3787 /// writeready masks or for timeout (in milliseconds) to occur. Returns
3788 /// the number of ready descriptors, or 0 in case of timeout, or < 0 in
3789 /// case of an error, with -2 being EINTR and -3 EBADF. In case of EINTR
3790 /// the errno has been reset and the method can be called again.
3791 
3792 int TUnixSystem::UnixSelect(Int_t nfds, TFdSet *readready, TFdSet *writeready,
3793  Long_t timeout)
3794 {
3795  int retcode;
3796 
3797  fd_set *rd = (readready) ? (fd_set*)readready->GetBits() : 0;
3798  fd_set *wr = (writeready) ? (fd_set*)writeready->GetBits() : 0;
3799 
3800  if (timeout >= 0) {
3801  struct timeval tv;
3802  tv.tv_sec = Int_t(timeout / 1000);
3803  tv.tv_usec = (timeout % 1000) * 1000;
3804  retcode = select(nfds, rd, wr, 0, &tv);
3805  } else {
3806  retcode = select(nfds, rd, wr, 0, 0);
3807  }
3808  if (retcode == -1) {
3809  if (GetErrno() == EINTR) {
3810  ResetErrno(); // errno is not self reseting
3811  return -2;
3812  }
3813  if (GetErrno() == EBADF)
3814  return -3;
3815  return -1;
3816  }
3817 
3818  return retcode;
3819 }
3820 
3821 //---- directories -------------------------------------------------------------
3822 
3823 ////////////////////////////////////////////////////////////////////////////////
3824 /// Returns the user's home directory.
3825 
3826 const char *TUnixSystem::UnixHomedirectory(const char *name)
3827 {
3828  static char path[kMAXPATHLEN], mydir[kMAXPATHLEN] = { '\0' };
3829  return UnixHomedirectory(name, path, mydir);
3830 }
3831 
3832 ////////////////////////////////////////////////////////////////////////////
3833 /// Returns the user's home directory.
3834 
3835 const char *TUnixSystem::UnixHomedirectory(const char *name, char *path, char *mydir)
3836 {
3837  struct passwd *pw;
3838  if (name) {
3839  pw = getpwnam(name);
3840  if (pw) {
3841  strncpy(path, pw->pw_dir, kMAXPATHLEN-1);
3842  path[kMAXPATHLEN-1] = '\0';
3843  return path;
3844  }
3845  } else {
3846  if (mydir[0])
3847  return mydir;
3848  pw = getpwuid(getuid());
3849  if (pw && pw->pw_dir) {
3850  strncpy(mydir, pw->pw_dir, kMAXPATHLEN-1);
3851  mydir[kMAXPATHLEN-1] = '\0';
3852  return mydir;
3853  } else if (gSystem->Getenv("HOME")) {
3854  strncpy(mydir, gSystem->Getenv("HOME"), kMAXPATHLEN-1);
3855  mydir[kMAXPATHLEN-1] = '\0';
3856  return mydir;
3857  }
3858  }
3859  return 0;
3860 }
3861 
3862 ////////////////////////////////////////////////////////////////////////////////
3863 /// Make a Unix file system directory. Returns 0 in case of success and
3864 /// -1 if the directory could not be created (either already exists or
3865 /// illegal path name).
3866 
3867 int TUnixSystem::UnixMakedir(const char *dir)
3868 {
3869  return ::mkdir(StripOffProto(dir, "file:"), 0755);
3870 }
3871 
3872 ////////////////////////////////////////////////////////////////////////////////
3873 /// Open a directory.
3874 
3875 void *TUnixSystem::UnixOpendir(const char *dir)
3876 {
3877  struct stat finfo;
3878 
3879  const char *edir = StripOffProto(dir, "file:");
3880 
3881  if (stat(edir, &finfo) < 0)
3882  return 0;
3883 
3884  if (!S_ISDIR(finfo.st_mode))
3885  return 0;
3886 
3887  return (void*) opendir(edir);
3888 }
3889 
3890 #if defined(_POSIX_SOURCE)
3891 // Posix does not require that the d_ino field be present, and some
3892 // systems do not provide it.
3893 # define REAL_DIR_ENTRY(dp) 1
3894 #else
3895 # define REAL_DIR_ENTRY(dp) (dp->d_ino != 0)
3896 #endif
3897 
3898 ////////////////////////////////////////////////////////////////////////////////
3899 /// Returns the next directory entry.
3900 
3901 const char *TUnixSystem::UnixGetdirentry(void *dirp1)
3902 {
3903  DIR *dirp = (DIR*)dirp1;
3904 #ifdef HAS_DIRENT
3905  struct dirent *dp;
3906 #else
3907  struct direct *dp;
3908 #endif
3909 
3910  if (dirp) {
3911  for (;;) {
3912  dp = readdir(dirp);
3913  if (dp == 0)
3914  return 0;
3915  if (REAL_DIR_ENTRY(dp))
3916  return dp->d_name;
3917  }
3918  }
3919  return 0;
3920 }
3921 
3922 //---- files -------------------------------------------------------------------
3923 
3924 ////////////////////////////////////////////////////////////////////////////////
3925 /// Get info about a file. Info is returned in the form of a FileStat_t
3926 /// structure (see TSystem.h).
3927 /// The function returns 0 in case of success and 1 if the file could
3928 /// not be stat'ed.
3929 
3930 int TUnixSystem::UnixFilestat(const char *fpath, FileStat_t &buf)
3931 {
3932  const char *path = StripOffProto(fpath, "file:");
3933  buf.fIsLink = kFALSE;
3934 
3935 #if defined(R__SEEK64)
3936  struct stat64 sbuf;
3937  if (path && lstat64(path, &sbuf) == 0) {
3938 #else
3939  struct stat sbuf;
3940  if (path && lstat(path, &sbuf) == 0) {
3941 #endif
3942  buf.fIsLink = S_ISLNK(sbuf.st_mode);
3943  if (buf.fIsLink) {
3944 #if defined(R__SEEK64)
3945  if (stat64(path, &sbuf) == -1) {
3946 #else
3947  if (stat(path, &sbuf) == -1) {
3948 #endif
3949  return 1;
3950  }
3951  }
3952  buf.fDev = sbuf.st_dev;
3953  buf.fIno = sbuf.st_ino;
3954  buf.fMode = sbuf.st_mode;
3955  buf.fUid = sbuf.st_uid;
3956  buf.fGid = sbuf.st_gid;
3957  buf.fSize = sbuf.st_size;
3958  buf.fMtime = sbuf.st_mtime;
3959 
3960  return 0;
3961  }
3962  return 1;
3963 }
3964 
3965 ////////////////////////////////////////////////////////////////////////////////
3966 /// Get info about a file system: id, bsize, bfree, blocks.
3967 /// Id is file system type (machine dependend, see statfs())
3968 /// Bsize is block size of file system
3969 /// Blocks is total number of blocks in file system
3970 /// Bfree is number of free blocks in file system
3971 /// The function returns 0 in case of success and 1 if the file system could
3972 /// not be stat'ed.
3973 
3974 int TUnixSystem::UnixFSstat(const char *path, Long_t *id, Long_t *bsize,
3975  Long_t *blocks, Long_t *bfree)
3976 {
3977  struct statfs statfsbuf;
3978 #if (defined(R__SOLARIS) && !defined(R__LINUX))
3979  if (statfs(path, &statfsbuf, sizeof(struct statfs), 0) == 0) {
3980  *id = statfsbuf.f_fstyp;
3981  *bsize = statfsbuf.f_bsize;
3982  *blocks = statfsbuf.f_blocks;
3983  *bfree = statfsbuf.f_bfree;
3984 #else
3985  if (statfs((char*)path, &statfsbuf) == 0) {
3986 #ifdef R__OBSD
3987  // Convert BSD filesystem names to Linux filesystem type numbers
3988  // where possible. Linux statfs uses a value of -1 to indicate
3989  // an unsupported field.
3990 
3991  if (!strcmp(statfsbuf.f_fstypename, MOUNT_FFS) ||
3992  !strcmp(statfsbuf.f_fstypename, MOUNT_MFS))
3993  *id = 0x11954;
3994  else if (!strcmp(statfsbuf.f_fstypename, MOUNT_NFS))
3995  *id = 0x6969;
3996  else if (!strcmp(statfsbuf.f_fstypename, MOUNT_MSDOS))
3997  *id = 0x4d44;
3998  else if (!strcmp(statfsbuf.f_fstypename, MOUNT_PROCFS))
3999  *id = 0x9fa0;
4000  else if (!strcmp(statfsbuf.f_fstypename, MOUNT_EXT2FS))
4001  *id = 0xef53;
4002  else if (!strcmp(statfsbuf.f_fstypename, MOUNT_CD9660))
4003  *id = 0x9660;
4004  else if (!strcmp(statfsbuf.f_fstypename, MOUNT_NCPFS))
4005  *id = 0x6969;
4006  else
4007  *id = -1;
4008 #else
4009  *id = statfsbuf.f_type;
4010 #endif
4011  *bsize = statfsbuf.f_bsize;
4012  *blocks = statfsbuf.f_blocks;
4013  *bfree = statfsbuf.f_bavail;
4014 #endif
4015  return 0;
4016  }
4017  return 1;
4018 }
4019 
4020 ////////////////////////////////////////////////////////////////////////////////
4021 /// Wait till child is finished.
4022 
4024 {
4025  int status;
4026  return (int) waitpid(0, &status, WNOHANG);
4027 }
4028 
4029 //---- RPC -------------------------------------------------------------------
4030 
4031 ////////////////////////////////////////////////////////////////////////////////
4032 /// Open a TCP/IP connection to server and connect to a service (i.e. port).
4033 /// Use tcpwindowsize to specify the size of the receive buffer, it has
4034 /// to be specified here to make sure the window scale option is set (for
4035 /// tcpwindowsize > 65KB and for platforms supporting window scaling).
4036 /// Is called via the TSocket constructor. Returns -1 in case of error.
4037 
4038 int TUnixSystem::UnixTcpConnect(const char *hostname, int port,
4039  int tcpwindowsize)
4040 {
4041  short sport;
4042  struct servent *sp;
4043 
4044  if ((sp = getservbyport(htons(port), kProtocolName)))
4045  sport = sp->s_port;
4046  else
4047  sport = htons(port);
4048 
4049  TInetAddress addr = gSystem->GetHostByName(hostname);
4050  if (!addr.IsValid()) return -1;
4051  UInt_t adr = htonl(addr.GetAddress());
4052 
4053  struct sockaddr_in server;
4054  memset(&server, 0, sizeof(server));
4055  memcpy(&server.sin_addr, &adr, sizeof(adr));
4056  server.sin_family = addr.GetFamily();
4057  server.sin_port = sport;
4058 
4059  // Create socket
4060  int sock;
4061  if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
4062  ::SysError("TUnixSystem::UnixTcpConnect", "socket (%s:%d)",
4063  hostname, port);
4064  return -1;
4065  }
4066 
4067  if (tcpwindowsize > 0) {
4068  gSystem->SetSockOpt(sock, kRecvBuffer, tcpwindowsize);
4069  gSystem->SetSockOpt(sock, kSendBuffer, tcpwindowsize);
4070  }
4071 
4072  while (connect(sock, (struct sockaddr*) &server, sizeof(server)) == -1) {
4073  if (GetErrno() == EINTR)
4074  ResetErrno();
4075  else {
4076  ::SysError("TUnixSystem::UnixTcpConnect", "connect (%s:%d)",
4077  hostname, port);
4078  close(sock);
4079  return -1;
4080  }
4081  }
4082  return sock;
4083 }
4084 
4085 
4086 ////////////////////////////////////////////////////////////////////////////////
4087 /// Creates a UDP socket connection
4088 /// Is called via the TSocket constructor. Returns -1 in case of error.
4089 
4090 int TUnixSystem::UnixUdpConnect(const char *hostname, int port)
4091 {
4092  short sport;
4093  struct servent *sp;
4094 
4095  if ((sp = getservbyport(htons(port), kProtocolName)))
4096  sport = sp->s_port;
4097  else
4098  sport = htons(port);
4099 
4100  TInetAddress addr = gSystem->GetHostByName(hostname);
4101  if (!addr.IsValid()) return -1;
4102  UInt_t adr = htonl(addr.GetAddress());
4103 
4104  struct sockaddr_in server;
4105  memset(&server, 0, sizeof(server));
4106  memcpy(&server.sin_addr, &adr, sizeof(adr));
4107  server.sin_family = addr.GetFamily();
4108  server.sin_port = sport;
4109 
4110  // Create socket
4111  int sock;
4112  if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
4113  ::SysError("TUnixSystem::UnixUdpConnect", "socket (%s:%d)",
4114  hostname, port);
4115  return -1;
4116  }
4117 
4118  while (connect(sock, (struct sockaddr*) &server, sizeof(server)) == -1) {
4119  if (GetErrno() == EINTR)
4120  ResetErrno();
4121  else {
4122  ::SysError("TUnixSystem::UnixUdpConnect", "connect (%s:%d)",
4123  hostname, port);
4124  close(sock);
4125  return -1;
4126  }
4127  }
4128  return sock;
4129 }
4130 
4131 ////////////////////////////////////////////////////////////////////////////////
4132 /// Connect to a Unix domain socket.
4133 
4135 {
4136  return UnixUnixConnect(TString::Format("%s/%d", kServerPath, port));
4137 }
4138 
4139 ////////////////////////////////////////////////////////////////////////////////
4140 /// Connect to a Unix domain socket. Returns -1 in case of error.
4141 
4142 int TUnixSystem::UnixUnixConnect(const char *sockpath)
4143 {
4144  if (!sockpath || strlen(sockpath) <= 0) {
4145  ::SysError("TUnixSystem::UnixUnixConnect", "socket path undefined");
4146  return -1;
4147  }
4148 
4149  int sock;
4150  struct sockaddr_un unserver;
4151  unserver.sun_family = AF_UNIX;
4152 
4153  if (strlen(sockpath) > sizeof(unserver.sun_path)-1) {
4154  ::Error("TUnixSystem::UnixUnixConnect", "socket path %s, longer than max allowed length (%u)",
4155  sockpath, (UInt_t)sizeof(unserver.sun_path)-1);
4156  return -1;
4157  }
4158  strcpy(unserver.sun_path, sockpath);
4159 
4160  // Open socket
4161  if ((sock = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
4162  ::SysError("TUnixSystem::UnixUnixConnect", "socket");
4163  return -1;
4164  }
4165 
4166  while (connect(sock, (struct sockaddr*) &unserver, strlen(unserver.sun_path)+2) == -1) {
4167  if (GetErrno() == EINTR)
4168  ResetErrno();
4169  else {
4170  ::SysError("TUnixSystem::UnixUnixConnect", "connect");
4171  close(sock);
4172  return -1;
4173  }
4174  }
4175  return sock;
4176 }
4177 
4178 ////////////////////////////////////////////////////////////////////////////////
4179 /// Open a socket, bind to it and start listening for TCP/IP connections
4180 /// on the port. If reuse is true reuse the address, backlog specifies
4181 /// how many sockets can be waiting to be accepted. If port is 0 a port
4182 /// scan will be done to find a free port. This option is mutual exlusive
4183 /// with the reuse option.
4184 /// Use tcpwindowsize to specify the size of the receive buffer, it has
4185 /// to be specified here to make sure the window scale option is set (for
4186 /// tcpwindowsize > 65KB and for platforms supporting window scaling).
4187 /// Returns socket fd or -1 if socket() failed, -2 if bind() failed
4188 /// or -3 if listen() failed.
4189 
4190 int TUnixSystem::UnixTcpService(int port, Bool_t reuse, int backlog,
4191  int tcpwindowsize)
4192 {
4193  const short kSOCKET_MINPORT = 5000, kSOCKET_MAXPORT = 15000;
4194  short sport, tryport = kSOCKET_MINPORT;
4195  struct servent *sp;
4196 
4197  if (port == 0 && reuse) {
4198  ::Error("TUnixSystem::UnixTcpService", "cannot do a port scan while reuse is true");
4199  return -1;
4200  }
4201 
4202  if ((sp = getservbyport(htons(port), kProtocolName)))
4203  sport = sp->s_port;
4204  else
4205  sport = htons(port);
4206 
4207  // Create tcp socket
4208  int sock;
4209  if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
4210  ::SysError("TUnixSystem::UnixTcpService", "socket");
4211  return -1;
4212  }
4213 
4214  if (reuse)
4215  gSystem->SetSockOpt(sock, kReuseAddr, 1);
4216 
4217  if (tcpwindowsize > 0) {
4218  gSystem->SetSockOpt(sock, kRecvBuffer, tcpwindowsize);
4219  gSystem->SetSockOpt(sock, kSendBuffer, tcpwindowsize);
4220  }
4221 
4222  struct sockaddr_in inserver;
4223  memset(&inserver, 0, sizeof(inserver));
4224  inserver.sin_family = AF_INET;
4225  inserver.sin_addr.s_addr = htonl(INADDR_ANY);
4226  inserver.sin_port = sport;
4227 
4228  // Bind socket
4229  if (port > 0) {
4230  if (::bind(sock, (struct sockaddr*) &inserver, sizeof(inserver))) {
4231  ::SysError("TUnixSystem::UnixTcpService", "bind");
4232  close(sock);
4233  return -2;
4234  }
4235  } else {
4236  int bret;
4237  do {
4238  inserver.sin_port = htons(tryport++);
4239  bret = ::bind(sock, (struct sockaddr*) &inserver, sizeof(inserver));
4240  } while (bret < 0 && GetErrno() == EADDRINUSE && tryport < kSOCKET_MAXPORT);
4241  if (bret < 0) {
4242  ::SysError("TUnixSystem::UnixTcpService", "bind (port scan)");
4243  close(sock);
4244  return -2;
4245  }
4246  }
4247 
4248  // Start accepting connections
4249  if (::listen(sock, backlog)) {
4250  ::SysError("TUnixSystem::UnixTcpService", "listen");
4251  close(sock);
4252  return -3;
4253  }
4254 
4255  return sock;
4256 }
4257 
4258 ////////////////////////////////////////////////////////////////////////////////
4259 /// Open a socket, bind to it and start listening for UDP connections
4260 /// on the port. If reuse is true reuse the address, backlog specifies
4261 /// how many sockets can be waiting to be accepted. If port is 0 a port
4262 /// scan will be done to find a free port. This option is mutual exlusive
4263 /// with the reuse option.
4264 
4265 int TUnixSystem::UnixUdpService(int port, int backlog)
4266 {
4267  const short kSOCKET_MINPORT = 5000, kSOCKET_MAXPORT = 15000;
4268  short sport, tryport = kSOCKET_MINPORT;
4269  struct servent *sp;
4270 
4271  if ((sp = getservbyport(htons(port), kProtocolName)))
4272  sport = sp->s_port;
4273  else
4274  sport = htons(port);
4275 
4276  // Create udp socket
4277  int sock;
4278  if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
4279  ::SysError("TUnixSystem::UnixUdpService", "socket");
4280  return -1;
4281  }
4282 
4283  struct sockaddr_in inserver;
4284  memset(&inserver, 0, sizeof(inserver));
4285  inserver.sin_family = AF_INET;
4286  inserver.sin_addr.s_addr = htonl(INADDR_ANY);
4287  inserver.sin_port = sport;
4288 
4289  // Bind socket
4290  if (port > 0) {
4291  if (::bind(sock, (struct sockaddr*) &inserver, sizeof(inserver))) {
4292  ::SysError("TUnixSystem::UnixUdpService", "bind");
4293  close(sock);
4294  return -2;
4295  }
4296  } else {
4297  int bret;
4298  do {
4299  inserver.sin_port = htons(tryport++);
4300  bret = ::bind(sock, (struct sockaddr*) &inserver, sizeof(inserver));
4301  } while (bret < 0 && GetErrno() == EADDRINUSE && tryport < kSOCKET_MAXPORT);
4302  if (bret < 0) {
4303  ::SysError("TUnixSystem::UnixUdpService", "bind (port scan)");
4304  close(sock);
4305  return -2;
4306  }
4307  }
4308 
4309  // Start accepting connections
4310  if (::listen(sock, backlog)) {
4311  ::SysError("TUnixSystem::UnixUdpService", "listen");
4312  close(sock);
4313  return -3;
4314  }
4315 
4316  return sock;
4317 }
4318 
4319 ////////////////////////////////////////////////////////////////////////////////
4320 /// Open a socket, bind to it and start listening for Unix domain connections
4321 /// to it. Returns socket fd or -1.
4322 
4323 int TUnixSystem::UnixUnixService(int port, int backlog)
4324 {
4325  int oldumask;
4326 
4327  // Assure that socket directory exists
4328  oldumask = umask(0);
4329  int res = ::mkdir(kServerPath, 0777);
4330  umask(oldumask);
4331 
4332  if (res == -1)
4333  return -1;
4334 
4335  // Socket path
4336  TString sockpath;
4337  sockpath.Form("%s/%d", kServerPath, port);
4338 
4339  // Remove old socket
4340  unlink(sockpath.Data());
4341 
4342  return UnixUnixService(sockpath, backlog);
4343 }
4344 
4345 ////////////////////////////////////////////////////////////////////////////////
4346 /// Open a socket on path 'sockpath', bind to it and start listening for Unix
4347 /// domain connections to it. Returns socket fd or -1.
4348 
4349 int TUnixSystem::UnixUnixService(const char *sockpath, int backlog)
4350 {
4351  if (!sockpath || strlen(sockpath) <= 0) {
4352  ::SysError("TUnixSystem::UnixUnixService", "socket path undefined");
4353  return -1;
4354  }
4355 
4356  struct sockaddr_un unserver;
4357  int sock;
4358 
4359  // Prepare structure
4360  memset(&unserver, 0, sizeof(unserver));
4361  unserver.sun_family = AF_UNIX;
4362 
4363  if (strlen(sockpath) > sizeof(unserver.sun_path)-1) {
4364  ::Error("TUnixSystem::UnixUnixService", "socket path %s, longer than max allowed length (%u)",
4365  sockpath, (UInt_t)sizeof(unserver.sun_path)-1);
4366  return -1;
4367  }
4368  strcpy(unserver.sun_path, sockpath);
4369 
4370  // Create socket
4371  if ((sock = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
4372  ::SysError("TUnixSystem::UnixUnixService", "socket");
4373  return -1;
4374  }
4375 
4376  if (::bind(sock, (struct sockaddr*) &unserver, strlen(unserver.sun_path)+2)) {
4377  ::SysError("TUnixSystem::UnixUnixService", "bind");
4378  close(sock);
4379  return -1;
4380  }
4381 
4382  // Start accepting connections
4383  if (::listen(sock, backlog)) {
4384  ::SysError("TUnixSystem::UnixUnixService", "listen");
4385  close(sock);
4386  return -1;
4387  }
4388 
4389  return sock;
4390 }
4391 
4392 ////////////////////////////////////////////////////////////////////////////////
4393 /// Receive exactly length bytes into buffer. Returns number of bytes
4394 /// received. Returns -1 in case of error, -2 in case of MSG_OOB
4395 /// and errno == EWOULDBLOCK, -3 in case of MSG_OOB and errno == EINVAL
4396 /// and -4 in case of kNoBlock and errno == EWOULDBLOCK.
4397 /// Returns -5 if pipe broken or reset by peer (EPIPE || ECONNRESET).
4398 
4399 int TUnixSystem::UnixRecv(int sock, void *buffer, int length, int flag)
4400 {
4401  ResetErrno();
4402 
4403  if (sock < 0) return -1;
4404 
4405  int once = 0;
4406  if (flag == -1) {
4407  flag = 0;
4408  once = 1;
4409  }
4410  if (flag == MSG_PEEK)
4411  once = 1;
4412 
4413  int n, nrecv = 0;
4414  char *buf = (char *)buffer;
4415 
4416  for (n = 0; n < length; n += nrecv) {
4417  if ((nrecv = recv(sock, buf+n, length-n, flag)) <= 0) {
4418  if (nrecv == 0)
4419  break; // EOF
4420  if (flag == MSG_OOB) {
4421  if (GetErrno() == EWOULDBLOCK)
4422  return -2;
4423  else if (GetErrno() == EINVAL)
4424  return -3;
4425  }
4426  if (GetErrno() == EWOULDBLOCK)
4427  return -4;
4428  else {
4429  if (GetErrno() != EINTR)
4430  ::SysError("TUnixSystem::UnixRecv", "recv");
4431  if (GetErrno() == EPIPE || GetErrno() == ECONNRESET)
4432  return -5;
4433  else
4434  return -1;
4435  }
4436  }
4437  if (once)
4438  return nrecv;
4439  }
4440  return n;
4441 }
4442 
4443 ////////////////////////////////////////////////////////////////////////////////
4444 /// Send exactly length bytes from buffer. Returns -1 in case of error,
4445 /// otherwise number of sent bytes. Returns -4 in case of kNoBlock and
4446 /// errno == EWOULDBLOCK. Returns -5 if pipe broken or reset by peer
4447 /// (EPIPE || ECONNRESET).
4448 
4449 int TUnixSystem::UnixSend(int sock, const void *buffer, int length, int flag)
4450 {
4451  if (sock < 0) return -1;
4452 
4453  int once = 0;
4454  if (flag == -1) {
4455  flag = 0;
4456  once = 1;
4457  }
4458 
4459  int n, nsent = 0;
4460  const char *buf = (const char *)buffer;
4461 
4462  for (n = 0; n < length; n += nsent) {
4463  if ((nsent = send(sock, buf+n, length-n, flag)) <= 0) {
4464  if (nsent == 0)
4465  break;
4466  if (GetErrno() == EWOULDBLOCK)
4467  return -4;
4468  else {
4469  if (GetErrno() != EINTR)
4470  ::SysError("TUnixSystem::UnixSend", "send");
4471  if (GetErrno() == EPIPE || GetErrno() == ECONNRESET)
4472  return -5;
4473  else
4474  return -1;
4475  }
4476  }
4477  if (once)
4478  return nsent;
4479  }
4480  return n;
4481 }
4482 
4483 //---- Dynamic Loading ---------------------------------------------------------
4484 
4485 ////////////////////////////////////////////////////////////////////////////////
4486 /// Get shared library search path. Static utility function.
4487 
4488 static const char *DynamicPath(const char *newpath = 0, Bool_t reset = kFALSE)
4489 {
4490  static TString dynpath;
4491  static Bool_t initialized = kFALSE;
4492  if (!initialized) {
4493  // force one time initialization of gROOT before we start
4494  // (otherwise it might be done as a side effect of gEnv->GetValue and
4495  // TROOT's initialization will call this routine).
4496  gROOT;
4497  }
4498 
4499  if (newpath) {
4500  dynpath = newpath;
4501  } else if (reset || !initialized) {
4502  initialized = kTRUE;
4503  TString rdynpath = gEnv->GetValue("Root.DynamicPath", (char*)0);
4504  rdynpath.ReplaceAll(": ", ":"); // in case DynamicPath was extended
4505  if (rdynpath.IsNull()) {
4506 #ifdef ROOTLIBDIR
4507  rdynpath = ".:"; rdynpath += ROOTLIBDIR;
4508 #else
4509  rdynpath = ".:"; rdynpath += gRootDir; rdynpath += "/lib";
4510 #endif
4511  }
4512  TString ldpath;
4513 #if defined (R__AIX)
4514  ldpath = gSystem->Getenv("LIBPATH");
4515 #elif defined(R__MACOSX)
4516  ldpath = gSystem->Getenv("DYLD_LIBRARY_PATH");
4517  if (!ldpath.IsNull())
4518  ldpath += ":";
4519  ldpath += gSystem->Getenv("LD_LIBRARY_PATH");
4520  if (!ldpath.IsNull())
4521  ldpath += ":";
4522  ldpath += gSystem->Getenv("DYLD_FALLBACK_LIBRARY_PATH");
4523 #else
4524  ldpath = gSystem->Getenv("LD_LIBRARY_PATH");
4525 #endif
4526  if (ldpath.IsNull())
4527  dynpath = rdynpath;
4528  else {
4529  dynpath = ldpath; dynpath += ":"; dynpath += rdynpath;
4530  }
4531 
4532 #ifdef ROOTLIBDIR
4533  if (!dynpath.Contains(ROOTLIBDIR)) {
4534  dynpath += ":"; dynpath += ROOTLIBDIR;
4535  }
4536 #else
4537  if (!dynpath.Contains(TString::Format("%s/lib", gRootDir))) {
4538  dynpath += ":"; dynpath += gRootDir; dynpath += "/lib";
4539  }
4540 #endif
4541  if (gCling) {
4542  dynpath += ":"; dynpath += gCling->GetSTLIncludePath();
4543  } else
4544  initialized = kFALSE;
4545 
4546 #if defined(R__WINGCC) || defined(R__MACOSX)
4547  if (!dynpath.EndsWith(":")) dynpath += ":";
4548  dynpath += "/usr/local/lib:/usr/X11R6/lib:/usr/lib:/lib:";
4549  dynpath += "/lib/x86_64-linux-gnu:/usr/local/lib64:/usr/lib64:/lib64:";
4550 #else
4551  // trick to get the system search path
4552  std::string cmd("LD_DEBUG=libs LD_PRELOAD=DOESNOTEXIST ls 2>&1");
4553  FILE *pf = popen(cmd.c_str (), "r");
4554  std::string result = "";
4555  char buffer[128];
4556  while (!feof(pf)) {
4557  if (fgets(buffer, 128, pf) != NULL)
4558  result += buffer;
4559  }
4560  pclose(pf);
4561  std::size_t from = result.find("search path=", result.find("(LD_LIBRARY_PATH)"));
4562  std::size_t to = result.find("(system search path)");
4563  if (from != std::string::npos && to != std::string::npos) {
4564  from += 12;
4565  std::string sys_path = result.substr(from, to-from);
4566  sys_path.erase(std::remove_if(sys_path.begin(), sys_path.end(), isspace), sys_path.end());
4567  if (!dynpath.EndsWith(":")) dynpath += ":";
4568  dynpath += sys_path.c_str();
4569  }
4570  dynpath.ReplaceAll("::", ":");
4571 #endif
4572  if (gDebug > 0) std::cout << "dynpath = " << dynpath.Data() << std::endl;
4573  }
4574  return dynpath;
4575 }
4576 
4577 ////////////////////////////////////////////////////////////////////////////////
4578 /// Add a new directory to the dynamic path.
4579 
4580 void TUnixSystem::AddDynamicPath(const char *path)
4581 {
4582  if (path) {
4583  TString oldpath = DynamicPath(0, kFALSE);
4584  oldpath.Append(":");
4585  oldpath.Append(path);
4586  DynamicPath(oldpath);
4587  }
4588 }
4589 
4590 ////////////////////////////////////////////////////////////////////////////////
4591 /// Return the dynamic path (used to find shared libraries).
4592 
4594 {
4595  return DynamicPath(0, kFALSE);
4596 }
4597 
4598 ////////////////////////////////////////////////////////////////////////////////
4599 /// Set the dynamic path to a new value.
4600 /// If the value of 'path' is zero, the dynamic path is reset to its
4601 /// default value.
4602 
4603 void TUnixSystem::SetDynamicPath(const char *path)
4604 {
4605  if (!path)
4606  DynamicPath(0, kTRUE);
4607  else
4608  DynamicPath(path);
4609 }
4610 
4611 ////////////////////////////////////////////////////////////////////////////////
4612 /// Returns the path of a shared library (searches for library in the
4613 /// shared library search path). If no file name extension is provided
4614 /// it first tries .so, .sl, .dl and then .a (for AIX).
4615 
4617 {
4618  char buf[PATH_MAX + 1];
4619  char *res = realpath(sLib.Data(), buf);
4620  if (res) sLib = buf;
4621  TString searchFor = sLib;
4623  return sLib;
4624  }
4625  sLib = searchFor;
4626  const char* lib = sLib.Data();
4627  int len = sLib.Length();
4628  if (len > 3 && (!strcmp(lib+len-3, ".so") ||
4629  !strcmp(lib+len-3, ".dl") ||
4630  !strcmp(lib+len-4, ".dll") ||
4631  !strcmp(lib+len-4, ".DLL") ||
4632  !strcmp(lib+len-6, ".dylib") ||
4633  !strcmp(lib+len-3, ".sl") ||
4634  !strcmp(lib+len-2, ".a"))) {
4636  return sLib;
4637  }
4638  if (!quiet)
4639  Error("FindDynamicLibrary",
4640  "%s does not exist in %s", searchFor.Data(), GetDynamicPath());
4641  return 0;
4642  }
4643  static const char* exts[] = {
4644  ".so", ".dll", ".dylib", ".sl", ".dl", ".a", 0 };
4645  const char** ext = exts;
4646  while (*ext) {
4647  TString fname(sLib);
4648  fname += *ext;
4649  ++ext;
4650  if (gSystem->FindFile(GetDynamicPath(), fname, kReadPermission)) {
4651  sLib.Swap(fname);
4652  return sLib;
4653  }
4654  }
4655 
4656  if (!quiet)
4657  Error("FindDynamicLibrary",
4658  "%s[.so | .dll | .dylib | .sl | .dl | .a] does not exist in %s",
4659  searchFor.Data(), GetDynamicPath());
4660 
4661  return 0;
4662 }
4663 
4664 //---- System, CPU and Memory info ---------------------------------------------
4665 
4666 #if defined(R__MACOSX)
4667 #include <sys/resource.h>
4668 #include <mach/mach.h>
4669 #include <mach/mach_error.h>
4670 
4671 ////////////////////////////////////////////////////////////////////////////////
4672 /// Get system info for Mac OS X.
4673 
4674 static void GetDarwinSysInfo(SysInfo_t *sysinfo)
4675 {
4676  FILE *p = gSystem->OpenPipe("sysctl -n kern.ostype hw.model hw.ncpu hw.cpufrequency "
4677  "hw.busfrequency hw.l2cachesize hw.memsize", "r");
4678  TString s;
4679  s.Gets(p);
4680  sysinfo->fOS = s;
4681  s.Gets(p);
4682  sysinfo->fModel = s;
4683  s.Gets(p);
4684  sysinfo->fCpus = s.Atoi();
4685  s.Gets(p);
4686  Long64_t t = s.Atoll();
4687  sysinfo->fCpuSpeed = Int_t(t / 1000000);
4688  s.Gets(p);
4689  t = s.Atoll();
4690  sysinfo->fBusSpeed = Int_t(t / 1000000);
4691  s.Gets(p);
4692  sysinfo->fL2Cache = s.Atoi() / 1024;
4693  s.Gets(p);
4694  t = s.Atoll();
4695  sysinfo->fPhysRam = Int_t(t / 1024 / 1024);
4696  gSystem->ClosePipe(p);
4697  p = gSystem->OpenPipe("hostinfo", "r");
4698  while (s.Gets(p)) {
4699  if (s.BeginsWith("Processor type: ")) {
4700  TPRegexp("Processor type: ([^ ]+).*").Substitute(s, "$1");
4701  sysinfo->fCpuType = s;
4702  }
4703  }
4704  gSystem->ClosePipe(p);
4705 }
4706 
4707 ////////////////////////////////////////////////////////////////////////////////
4708 /// Get CPU load on Mac OS X.
4709 
4710 static void ReadDarwinCpu(long *ticks)
4711 {
4712  mach_msg_type_number_t count;
4713  kern_return_t kr;
4714  host_cpu_load_info_data_t cpu;
4715 
4716  ticks[0] = ticks[1] = ticks[2] = ticks[3] = 0;
4717 
4718  count = HOST_CPU_LOAD_INFO_COUNT;
4719  kr = host_statistics(mach_host_self(), HOST_CPU_LOAD_INFO, (host_info_t)&cpu, &count);
4720  if (kr != KERN_SUCCESS) {
4721  ::Error("TUnixSystem::ReadDarwinCpu", "host_statistics: %s", mach_error_string(kr));
4722  } else {
4723  ticks[0] = cpu.cpu_ticks[CPU_STATE_USER];
4724  ticks[1] = cpu.cpu_ticks[CPU_STATE_SYSTEM];
4725  ticks[2] = cpu.cpu_ticks[CPU_STATE_IDLE];
4726  ticks[3] = cpu.cpu_ticks[CPU_STATE_NICE];
4727  }
4728 }
4729 
4730 ////////////////////////////////////////////////////////////////////////////////
4731 /// Get CPU stat for Mac OS X. Use sampleTime to set the interval over which
4732 /// the CPU load will be measured, in ms (default 1000).
4733 
4734 static void GetDarwinCpuInfo(CpuInfo_t *cpuinfo, Int_t sampleTime)
4735 {
4736  Double_t avg[3];
4737  if (getloadavg(avg, sizeof(avg)) < 0) {
4738  ::Error("TUnixSystem::GetDarwinCpuInfo", "getloadavg failed");
4739  } else {
4740  cpuinfo->fLoad1m = (Float_t)avg[0];
4741  cpuinfo->fLoad5m = (Float_t)avg[1];
4742  cpuinfo->fLoad15m = (Float_t)avg[2];
4743  }
4744 
4745  Long_t cpu_ticks1[4], cpu_ticks2[4];
4746  ReadDarwinCpu(cpu_ticks1);
4747  gSystem->Sleep(sampleTime);
4748  ReadDarwinCpu(cpu_ticks2);
4749 
4750  Long_t userticks = (cpu_ticks2[0] + cpu_ticks2[3]) -
4751  (cpu_ticks1[0] + cpu_ticks1[3]);
4752  Long_t systicks = cpu_ticks2[1] - cpu_ticks1[1];
4753  Long_t idleticks = cpu_ticks2[2] - cpu_ticks1[2];
4754  if (userticks < 0) userticks = 0;
4755  if (systicks < 0) systicks = 0;
4756  if (idleticks < 0) idleticks = 0;
4757  Long_t totalticks = userticks + systicks + idleticks;
4758  if (totalticks) {
4759  cpuinfo->fUser = ((Float_t)(100 * userticks)) / ((Float_t)totalticks);
4760  cpuinfo->fSys = ((Float_t)(100 * systicks)) / ((Float_t)totalticks);
4761  cpuinfo->fTotal = cpuinfo->fUser + cpuinfo->fSys;
4762  cpuinfo->fIdle = ((Float_t)(100 * idleticks)) / ((Float_t)totalticks);
4763  }
4764 }
4765 
4766 ////////////////////////////////////////////////////////////////////////////////
4767 /// Get VM stat for Mac OS X.
4768 
4769 static void GetDarwinMemInfo(MemInfo_t *meminfo)
4770 {
4771  static Int_t pshift = 0;
4772  static DIR *dirp;
4773  vm_statistics_data_t vm_info;
4774  mach_msg_type_number_t count;
4775  kern_return_t kr;
4776  struct dirent *dp;
4777  Long64_t total, used, free, swap_total, swap_used;
4778 
4779  count = HOST_VM_INFO_COUNT;
4780  kr = host_statistics(mach_host_self(), HOST_VM_INFO, (host_info_t)&vm_info, &count);
4781  if (kr != KERN_SUCCESS) {
4782  ::Error("TUnixSystem::GetDarwinMemInfo", "host_statistics: %s", mach_error_string(kr));
4783  return;
4784  }
4785  if (pshift == 0) {
4786  for (int psize = getpagesize(); psize > 1; psize >>= 1)
4787  pshift++;
4788  }
4789 
4790  used = (Long64_t)(vm_info.active_count + vm_info.inactive_count + vm_info.wire_count) << pshift;
4791  free = (Long64_t)(vm_info.free_count) << pshift;
4792  total = (Long64_t)(vm_info.active_count + vm_info.inactive_count + vm_info.free_count + vm_info.wire_count) << pshift;
4793 
4794  // Swap is available at same time as mem, so grab values here.
4795  swap_used = vm_info.pageouts << pshift;
4796 
4797  // Figure out total swap. This adds up the size of the swapfiles */
4798  dirp = opendir("/private/var/vm");
4799  if (!dirp)
4800  return;
4801 
4802  swap_total = 0;
4803  while ((dp = readdir(dirp)) != 0) {
4804  struct stat sb;
4805  char fname [MAXNAMLEN];
4806  if (strncmp(dp->d_name, "swapfile", 8))
4807  continue;
4808  strlcpy(fname, "/private/var/vm/",MAXNAMLEN);
4809  strlcat (fname, dp->d_name,MAXNAMLEN);
4810  if (stat(fname, &sb) < 0)
4811  continue;
4812  swap_total += sb.st_size;
4813  }
4814  closedir(dirp);
4815 
4816  meminfo->fMemTotal = (Int_t) (total >> 20); // divide by 1024 * 1024
4817  meminfo->fMemUsed = (Int_t) (used >> 20);
4818  meminfo->fMemFree = (Int_t) (free >> 20);
4819  meminfo->fSwapTotal = (Int_t) (swap_total >> 20);
4820  meminfo->fSwapUsed = (Int_t) (swap_used >> 20);
4821  meminfo->fSwapFree = meminfo->fSwapTotal - meminfo->fSwapUsed;
4822 }
4823 
4824 ////////////////////////////////////////////////////////////////////////////////
4825 /// Get process info for this process on Mac OS X.
4826 /// Code largely taken from:
4827 /// http://www.opensource.apple.com/source/top/top-15/libtop.c
4828 /// The virtual memory usage is slightly over estimated as we don't
4829 /// subtract shared regions, but the value makes more sense
4830 /// then pure vsize, which is useless on 64-bit machines.
4831 
4832 static void GetDarwinProcInfo(ProcInfo_t *procinfo)
4833 {
4834 #ifdef _LP64
4835 #define vm_region vm_region_64
4836 #endif
4837 
4838 // taken from <mach/shared_memory_server.h> which is obsoleted in 10.5
4839 #define GLOBAL_SHARED_TEXT_SEGMENT 0x90000000U
4840 #define GLOBAL_SHARED_DATA_SEGMENT 0xA0000000U
4841 #define SHARED_TEXT_REGION_SIZE 0x10000000
4842 #define SHARED_DATA_REGION_SIZE 0x10000000
4843 
4844  struct rusage ru;
4845  if (getrusage(RUSAGE_SELF, &ru) < 0) {
4846  ::SysError("TUnixSystem::GetDarwinProcInfo", "getrusage failed");
4847  } else {
4848  procinfo->fCpuUser = (Float_t)(ru.ru_utime.tv_sec) +
4849  ((Float_t)(ru.ru_utime.tv_usec) / 1000000.);
4850  procinfo->fCpuSys = (Float_t)(ru.ru_stime.tv_sec) +
4851  ((Float_t)(ru.ru_stime.tv_usec) / 1000000.);
4852  }
4853 
4854  task_basic_info_data_t ti;
4855  mach_msg_type_number_t count;
4856  kern_return_t kr;
4857 
4858  task_t a_task = mach_task_self();
4859 
4860  count = TASK_BASIC_INFO_COUNT;
4861  kr = task_info(a_task, TASK_BASIC_INFO, (task_info_t)&ti, &count);
4862  if (kr != KERN_SUCCESS) {
4863  ::Error("TUnixSystem::GetDarwinProcInfo", "task_info: %s", mach_error_string(kr));
4864  } else {
4865  // resident size does not require any calculation. Virtual size
4866  // needs to be adjusted if traversing memory objects do not include the
4867  // globally shared text and data regions
4868  mach_port_t object_name;
4869  vm_address_t address;
4870  vm_region_top_info_data_t info;
4871  vm_size_t vsize, vprvt, rsize, size;
4872  rsize = ti.resident_size;
4873  vsize = ti.virtual_size;
4874  vprvt = 0;
4875  for (address = 0; ; address += size) {
4876  // get memory region
4877  count = VM_REGION_TOP_INFO_COUNT;
4878  if (vm_region(a_task, &address, &size,
4879  VM_REGION_TOP_INFO, (vm_region_info_t)&info, &count,
4880  &object_name) != KERN_SUCCESS) {
4881  // no more memory regions.
4882  break;
4883  }
4884 
4885  if (address >= GLOBAL_SHARED_TEXT_SEGMENT &&
4886  address < (GLOBAL_SHARED_DATA_SEGMENT + SHARED_DATA_REGION_SIZE)) {
4887  // This region is private shared.
4888  // Check if this process has the globally shared
4889  // text and data regions mapped in. If so, adjust
4890  // virtual memory size and exit loop.
4891  if (info.share_mode == SM_EMPTY) {
4892  vm_region_basic_info_data_64_t b_info;
4893  count = VM_REGION_BASIC_INFO_COUNT_64;
4894  if (vm_region_64(a_task, &address,
4895  &size, VM_REGION_BASIC_INFO,
4896  (vm_region_info_t)&b_info, &count,
4897  &object_name) != KERN_SUCCESS) {
4898  break;
4899  }
4900 
4901  if (b_info.reserved) {
4902  vsize -= (SHARED_TEXT_REGION_SIZE + SHARED_DATA_REGION_SIZE);
4903  //break; // only for vsize
4904  }
4905  }
4906  // Short circuit the loop if this isn't a shared
4907  // private region, since that's the only region
4908  // type we care about within the current address range.
4909  if (info.share_mode != SM_PRIVATE) {
4910  continue;
4911  }
4912  }
4913  switch (info.share_mode) {
4914  case SM_COW: {
4915  if (info.ref_count == 1) {
4916  vprvt += size;
4917  } else {
4918  vprvt += info.private_pages_resident * getpagesize();
4919  }
4920  break;
4921  }
4922  case SM_PRIVATE: {
4923  vprvt += size;
4924  break;
4925  }
4926  default:
4927  break;
4928  }
4929  }
4930 
4931  procinfo->fMemResident = (Long_t)(rsize / 1024);
4932  //procinfo->fMemVirtual = (Long_t)(vsize / 1024);
4933  procinfo->fMemVirtual = (Long_t)(vprvt / 1024);
4934  }
4935 }
4936 #endif
4937 
4938 #if defined(R__LINUX)
4939 ////////////////////////////////////////////////////////////////////////////////
4940 /// Get system info for Linux. Only fBusSpeed is not set.
4941 
4942 static void GetLinuxSysInfo(SysInfo_t *sysinfo)
4943 {
4944  TString s;
4945  FILE *f = fopen("/proc/cpuinfo", "r");
4946  if (f) {
4947  while (s.Gets(f)) {
4948  if (s.BeginsWith("model name")) {
4949  TPRegexp("^.+: *(.*$)").Substitute(s, "$1");
4950  sysinfo->fModel = s;
4951  }
4952  if (s.BeginsWith("cpu MHz")) {
4953  TPRegexp("^.+: *([^ ]+).*").Substitute(s, "$1");
4954  sysinfo->fCpuSpeed = s.Atoi();
4955  }
4956  if (s.BeginsWith("cache size")) {
4957  TPRegexp("^.+: *([^ ]+).*").Substitute(s, "$1");
4958  sysinfo->fL2Cache = s.Atoi();
4959  }
4960  if (s.BeginsWith("processor")) {
4961  TPRegexp("^.+: *([^ ]+).*").Substitute(s, "$1");
4962  sysinfo->fCpus = s.Atoi();
4963  sysinfo->fCpus++;
4964  }
4965  }
4966  fclose(f);
4967  }
4968 
4969  f = fopen("/proc/meminfo", "r");
4970  if (f) {
4971  while (s.Gets(f)) {
4972  if (s.BeginsWith("MemTotal")) {
4973  TPRegexp("^.+: *([^ ]+).*").Substitute(s, "$1");
4974  sysinfo->fPhysRam = (s.Atoi() / 1024);
4975  break;
4976  }
4977  }
4978  fclose(f);
4979  }
4980 
4981  f = gSystem->OpenPipe("uname -s -p", "r");
4982  if (f) {
4983  s.Gets(f);
4984  Ssiz_t from = 0;
4985  s.Tokenize(sysinfo->fOS, from);
4986  s.Tokenize(sysinfo->fCpuType, from);
4987  gSystem->ClosePipe(f);
4988  }
4989 }
4990 
4991 ////////////////////////////////////////////////////////////////////////////////
4992 /// Get CPU load on Linux.
4993 
4994 static void ReadLinuxCpu(long *ticks)
4995 {
4996  ticks[0] = ticks[1] = ticks[2] = ticks[3] = 0;
4997 
4998  TString s;
4999  FILE *f = fopen("/proc/stat", "r");
5000  if (!f) return;
5001  s.Gets(f);
5002  // user, user nice, sys, idle
5003  sscanf(s.Data(), "%*s %ld %ld %ld %ld", &ticks[0], &ticks[3], &ticks[1], &ticks[2]);
5004  fclose(f);
5005 }
5006 
5007 ////////////////////////////////////////////////////////////////////////////////
5008 /// Get CPU stat for Linux. Use sampleTime to set the interval over which
5009 /// the CPU load will be measured, in ms (default 1000).
5010 
5011 static void GetLinuxCpuInfo(CpuInfo_t *cpuinfo, Int_t sampleTime)
5012 {
5013  Double_t avg[3] = { -1., -1., -1. };
5014 #ifndef R__WINGCC
5015  if (getloadavg(avg, sizeof(avg)) < 0) {
5016  ::Error("TUnixSystem::GetLinuxCpuInfo", "getloadavg failed");
5017  } else
5018 #endif
5019  {
5020  cpuinfo->fLoad1m = (Float_t)avg[0];
5021  cpuinfo->fLoad5m = (Float_t)avg[1];
5022  cpuinfo->fLoad15m = (Float_t)avg[2];
5023  }
5024 
5025  Long_t cpu_ticks1[4], cpu_ticks2[4];
5026  ReadLinuxCpu(cpu_ticks1);
5027  gSystem->Sleep(sampleTime);
5028  ReadLinuxCpu(cpu_ticks2);
5029 
5030  Long_t userticks = (cpu_ticks2[0] + cpu_ticks2[3]) -
5031  (cpu_ticks1[0] + cpu_ticks1[3]);
5032  Long_t systicks = cpu_ticks2[1] - cpu_ticks1[1];
5033  Long_t idleticks = cpu_ticks2[2] - cpu_ticks1[2];
5034  if (userticks < 0) userticks = 0;
5035  if (systicks < 0) systicks = 0;
5036  if (idleticks < 0) idleticks = 0;
5037  Long_t totalticks = userticks + systicks + idleticks;
5038  if (totalticks) {
5039  cpuinfo->fUser = ((Float_t)(100 * userticks)) / ((Float_t)totalticks);
5040  cpuinfo->fSys = ((Float_t)(100 * systicks)) / ((Float_t)totalticks);
5041  cpuinfo->fTotal = cpuinfo->fUser + cpuinfo->fSys;
5042  cpuinfo->fIdle = ((Float_t)(100 * idleticks)) / ((Float_t)totalticks);
5043  }
5044 }
5045 
5046 ////////////////////////////////////////////////////////////////////////////////
5047 /// Get VM stat for Linux.
5048 
5049 static void GetLinuxMemInfo(MemInfo_t *meminfo)
5050 {
5051  TString s;
5052  FILE *f = fopen("/proc/meminfo", "r");
5053  if (!f) return;
5054  while (s.Gets(f)) {
5055  if (s.BeginsWith("MemTotal")) {
5056  TPRegexp("^.+: *([^ ]+).*").Substitute(s, "$1");
5057  meminfo->fMemTotal = (s.Atoi() / 1024);
5058  }
5059  if (s.BeginsWith("MemFree")) {
5060  TPRegexp("^.+: *([^ ]+).*").Substitute(s, "$1");
5061  meminfo->fMemFree = (s.Atoi() / 1024);
5062  }
5063  if (s.BeginsWith("SwapTotal")) {
5064  TPRegexp("^.+: *([^ ]+).*").Substitute(s, "$1");
5065  meminfo->fSwapTotal = (s.Atoi() / 1024);
5066  }
5067  if (s.BeginsWith("SwapFree")) {
5068  TPRegexp("^.+: *([^ ]+).*").Substitute(s, "$1");
5069  meminfo->fSwapFree = (s.Atoi() / 1024);
5070  }
5071  }
5072  fclose(f);
5073 
5074  meminfo->fMemUsed = meminfo->fMemTotal - meminfo->fMemFree;
5075  meminfo->fSwapUsed = meminfo->fSwapTotal - meminfo->fSwapFree;
5076 }
5077 
5078 ////////////////////////////////////////////////////////////////////////////////
5079 /// Get process info for this process on Linux.
5080 
5081 static void GetLinuxProcInfo(ProcInfo_t *procinfo)
5082 {
5083  struct rusage ru;
5084  if (getrusage(RUSAGE_SELF, &ru) < 0) {
5085  ::SysError("TUnixSystem::GetLinuxProcInfo", "getrusage failed");
5086  } else {
5087  procinfo->fCpuUser = (Float_t)(ru.ru_utime.tv_sec) +
5088  ((Float_t)(ru.ru_utime.tv_usec) / 1000000.);
5089  procinfo->fCpuSys = (Float_t)(ru.ru_stime.tv_sec) +
5090  ((Float_t)(ru.ru_stime.tv_usec) / 1000000.);
5091  }
5092 
5093  procinfo->fMemVirtual = -1;
5094  procinfo->fMemResident = -1;
5095  TString s;
5096  FILE *f = fopen(TString::Format("/proc/%d/statm", gSystem->GetPid()), "r");
5097  if (f) {
5098  s.Gets(f);
5099  fclose(f);
5100  Long_t total, rss;
5101  sscanf(s.Data(), "%ld %ld", &total, &rss);
5102  procinfo->fMemVirtual = total * (getpagesize() / 1024);
5103  procinfo->fMemResident = rss * (getpagesize() / 1024);
5104  }
5105 }
5106 #endif
5107 
5108 ////////////////////////////////////////////////////////////////////////////////
5109 /// Returns static system info, like OS type, CPU type, number of CPUs
5110 /// RAM size, etc into the SysInfo_t structure. Returns -1 in case of error,
5111 /// 0 otherwise.
5112 
5114 {
5115  if (!info) return -1;
5116 
5117  static SysInfo_t sysinfo;
5118 
5119  if (!sysinfo.fCpus) {
5120 #if defined(R__MACOSX)
5121  GetDarwinSysInfo(&sysinfo);
5122 #elif defined(R__LINUX)
5123  GetLinuxSysInfo(&sysinfo);
5124 #endif
5125  }
5126 
5127  *info = sysinfo;
5128 
5129  return 0;
5130 }
5131 
5132 ////////////////////////////////////////////////////////////////////////////////
5133 /// Returns cpu load average and load info into the CpuInfo_t structure.
5134 /// Returns -1 in case of error, 0 otherwise. Use sampleTime to set the
5135 /// interval over which the CPU load will be measured, in ms (default 1000).
5136 
5137 int TUnixSystem::GetCpuInfo(CpuInfo_t *info, Int_t sampleTime) const
5138 {
5139  if (!info) return -1;
5140 
5141 #if defined(R__MACOSX)
5142  GetDarwinCpuInfo(info, sampleTime);
5143 #elif defined(R__LINUX)
5144  GetLinuxCpuInfo(info, sampleTime);
5145 #endif
5146 
5147  return 0;
5148 }
5149 
5150 ////////////////////////////////////////////////////////////////////////////////
5151 /// Returns ram and swap memory usage info into the MemInfo_t structure.
5152 /// Returns -1 in case of error, 0 otherwise.
5153 
5155 {
5156  if (!info) return -1;
5157 
5158 #if defined(R__MACOSX)
5159  GetDarwinMemInfo(info);
5160 #elif defined(R__LINUX)
5161  GetLinuxMemInfo(info);
5162 #endif
5163 
5164  return 0;
5165 }
5166 
5167 ////////////////////////////////////////////////////////////////////////////////
5168 /// Returns cpu and memory used by this process into the ProcInfo_t structure.
5169 /// Returns -1 in case of error, 0 otherwise.
5170 
5172 {
5173  if (!info) return -1;
5174 
5175 #if defined(R__MACOSX)
5176  GetDarwinProcInfo(info);
5177 #elif defined(R__LINUX)
5178  GetLinuxProcInfo(info);
5179 #endif
5180 
5181  return 0;
5182 }
Bool_t IsPathLocal(const char *path)
Returns TRUE if the url in 'path' points to the local file system.
Int_t fMemFree
Definition: TSystem.h:193
const char * TempDirectory() const
Return a user configured or systemwide directory to create temporary files in.
Int_t fGid
Definition: TSystem.h:151
void(* SigHandler_t)(ESignals)
Definition: TUnixSystem.h:34
int GetPid()
Get process id.
virtual const char * BaseName(const char *pathname)
Base name of a file name. Base name of /user/root is root.
Definition: TSystem.cxx:928
TString fStdErrTty
Definition: TSystem.h:217
int GetFsInfo(const char *path, Long_t *id, Long_t *bsize, Long_t *blocks, Long_t *bfree)
Get info about a file system: id, bsize, bfree, blocks.
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:1265
Float_t fLoad15m
Definition: TSystem.h:179
double read(const std::string &file_name)
reading
void AddTimer(TTimer *ti)
Add timer to list of system timers.
virtual void SetWriteReady()
void ListSymbols(const char *module, const char *re="")
List symbols in a shared library.
virtual int GetPid()
Get process id.
Definition: TSystem.cxx:711
An array of TObjects.
Definition: TObjArray.h:39
void StackTrace()
Print a stack trace.
Bool_t AccessPathName(const char *path, EAccessMode mode=kFileExists)
Returns FALSE if one can access a file using the specified access mode.
int pw_uid
Definition: TWinNTSystem.h:52
virtual Bool_t Notify()
Notify when event occurred on descriptor associated with this handler.
virtual Bool_t IsPathLocal(const char *path)
Returns TRUE if the url in 'path' points to the local file system.
Definition: TSystem.cxx:1274
long long Long64_t
Definition: RtypesCore.h:69
Int_t fBusSpeed
Definition: TSystem.h:167
int GetMemInfo(MemInfo_t *info) const
Returns ram and swap memory usage info into the MemInfo_t structure.
Int_t fPhysRam
Definition: TSystem.h:169
Int_t fSigcnt
Definition: TSystem.h:275
const char * GetError()
Return system error string.
Int_t fReadOffSet
Definition: TSystem.h:220
Bool_t IsSync() const
virtual const char * WorkingDirectory()
Return working directory.
Definition: TSystem.cxx:865
void Sleep(UInt_t milliSec)
Sleep milliSec milliseconds.
char * pw_shell
Definition: TWinNTSystem.h:57
Bool_t Init()
Initialize Unix system interface.
const char * FindFile(const char *search, TString &file, EAccessMode mode=kFileExists)
Find location of file "wfil" in a search path.
Float_t fSys
Definition: TSystem.h:181
static void UnixResetSignal(ESignals sig)
Restore old signal handler for specified signal.
Bool_t ExpandPathName(TString &patbuf)
Expand a pathname getting rid of special shell characters like ~.
double write(int n, const std::string &file_name, const std::string &vector_type, int compress=0)
writing
std::string GetWorkingDirectory() const
Return working directory.
virtual ~TUnixSystem()
Reset to original state.
static const char * GetExePath()
ClassImp(TSeqCollection) Int_t TSeqCollection TIter next(this)
Return index of object in collection.
R__EXTERN TVirtualMutex * gSystemMutex
Definition: TSystem.h:236
Ssiz_t Length() const
Definition: TString.h:390
TLine * line
void Fatal(const char *location, const char *msgfmt,...)
Collectable string class.
Definition: TObjString.h:32
float Float_t
Definition: RtypesCore.h:53
int gr_gid
Definition: TWinNTSystem.h:64
int GetPathInfo(const char *path, FileStat_t &buf)
Get info about a file.
static int UnixFilestat(const char *path, FileStat_t &buf)
Get info about a file.
Int_t GetFPEMask()
Return the bitmap of conditions that trigger a floating point exception.
static int UnixTcpConnect(const char *hostname, int port, int tcpwindowsize)
Open a TCP/IP connection to server and connect to a service (i.e.
TString fOS
Definition: TSystem.h:162
static int UnixRecv(int sock, void *buf, int len, int flag)
Receive exactly length bytes into buffer.
int GetSockOpt(int sock, int option, int *val)
Get socket option.
Int_t fUid
Definition: TSystem.h:139
TString & ReplaceAll(const TString &s1, const TString &s2)
Definition: TString.h:635
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:1363
Bool_t DispatchTimers(Bool_t mode)
Handle and dispatch timers.
const char * FindDynamicLibrary(TString &lib, Bool_t quiet=kFALSE)
Returns the path of a shared library (searches for library in the shared library search path)...
void demangle(char *_codeInfo, TString &_str)
demangle symbols
TH1 * h
Definition: legend2.C:5
TString fStdOutTty
Definition: TSystem.h:216
char * gr_name
Definition: TWinNTSystem.h:62
TString fGroup
Definition: TSystem.h:153
int Symlink(const char *from, const char *to)
Create a symlink from file1 to file2.
This class represents an Internet Protocol (IP) address.
Definition: TInetAddress.h:40
virtual int MakeDirectory(const char *name)
Make a directory.
Definition: TSystem.cxx:821
virtual void AddSignalHandler(TSignalHandler *sh)
Add a signal handler to list of system signal handlers.
Definition: TSystem.cxx:536
TString fWdpath
Definition: TSystem.h:276
int MakeDirectory(const char *name)
Make a Unix file system directory.
Regular expression class.
Definition: TRegexp.h:35
Int_t fStdOutDup
Definition: TSystem.h:218
#define gROOT
Definition: TROOT.h:340
Int_t Select(TList *active, Long_t timeout)
Select on file descriptors.
Int_t GetGid(const char *group=0)
Returns the group's id. If group = 0, returns current user's group.
static Long64_t UnixNow()
Get current time in milliseconds since 0:00 Jan 1 1995.
virtual int Load(const char *module, const char *entry="", Bool_t system=kFALSE)
Load a shared library.
Definition: TSystem.cxx:1818
Basic string class.
Definition: TString.h:137
void SetProgname(const char *name)
Set the application name (from command line, argv[0]) and copy it in gProgName.
TSeqCollection * fSignalHandler
Definition: TSystem.h:287
static struct Signalmap_t gSignalMap[kMAXSIGNALS]
TFileHandler * RemoveFileHandler(TFileHandler *fh)
Remove a file handler from the list of file handlers.
TAlienJobStatus * status
Definition: TAlienJob.cxx:51
int Int_t
Definition: RtypesCore.h:41
virtual const char * DirName(const char *pathname)
Return the directory name in pathname.
Definition: TSystem.cxx:996
bool Bool_t
Definition: RtypesCore.h:59
virtual TTimer * RemoveTimer(TTimer *t)
Remove timer from list of system timers.
Definition: TSystem.cxx:485
TArc * a
Definition: textangle.C:12
R__EXTERN TVirtualMutex * gROOTMutex
Definition: TROOT.h:63
const Bool_t kFALSE
Definition: Rtypes.h:92
Int_t Substitute(TString &s, const TString &replace, const TString &mods="", Int_t start=0, Int_t nMatchMax=10)
Substitute replaces the string s by a new string in which matching patterns are replaced by the repla...
Definition: TPRegexp.cxx:468
const char * HostName()
Return the system's host name.
int SendRaw(int sock, const void *buffer, int length, int flag)
Send exactly length bytes from buffer.
int Umask(Int_t mask)
Set the process file creation mode mask.
#define gInterpreter
Definition: TInterpreter.h:502
virtual char * Which(const char *search, const char *file, EAccessMode mode=kFileExists)
Find location of file in a search path.
Definition: TSystem.cxx:1511
void Break(const char *location, const char *msgfmt,...)
Long_t fMtime
Definition: TSystem.h:142
void Syslog(ELogLevel level, const char *mess)
Send mess to syslog daemon.
virtual FILE * OpenPipe(const char *command, const char *mode)
Open a pipe.
Definition: TSystem.cxx:666
#define REAL_DIR_ENTRY(dp)
virtual void ResetReadyMask()
TString & Prepend(const char *cs)
Definition: TString.h:604
R__EXTERN TApplication * gApplication
Definition: TApplication.h:171
Basic time type with millisecond precision.
Definition: TTime.h:29
static void UnixSigAlarmInterruptsSyscalls(Bool_t set)
When the argument is true the SIGALRM signal handler is set so that interrupted syscalls will not be ...
int ConnectService(const char *server, int port, int tcpwindowsize, const char *protocol="tcp")
Connect to service servicename on server servername.
const char * HomeDirectory(const char *userName=0)
Return the user's home directory.
const char * kShellMeta
TString fModel
Definition: TSystem.h:163
Bool_t fInsideNotify
Definition: TSystem.h:278
Long64_t fSize
Definition: TSystem.h:141
size_t
Definition: TBuffer.cxx:28
Bool_t BeginsWith(const char *s, ECaseCompare cmp=kExact) const
Definition: TString.h:558
void Exit(int code, Bool_t mode=kTRUE)
Exit the application.
int Unlink(const char *name)
Unlink, i.e.
Int_t fUid
Definition: TSystem.h:150
#define UTMP_FILE
static int UnixSelect(Int_t nfds, TFdSet *readready, TFdSet *writeready, Long_t timeout)
Wait for events on the file descriptors specified in the readready and writeready masks or for timeou...
virtual TFileHandler * RemoveFileHandler(TFileHandler *fh)
Remove a file handler from the list of file handlers.
Definition: TSystem.cxx:568
void Reset()
Definition: TCollection.h:161
virtual int mkdir(const char *name, Bool_t recursive=kFALSE)
Make a file system directory.
Definition: TSystem.cxx:900
void SysError(const char *location, const char *msgfmt,...)
virtual const char * FindFile(const char *search, TString &file, EAccessMode mode=kFileExists)
Find location of file in a search path.
Definition: TSystem.cxx:1501
static Int_t GetErrno()
Static function returning system error number.
Definition: TSystem.cxx:264
Int_t fMode
Definition: TSystem.h:138
TString fHostname
Definition: TSystem.h:277
const char * String
Definition: TXMLSetup.cxx:94
const char * Data() const
Definition: TString.h:349
virtual Bool_t Notify()
Notify when signal occurs.
virtual const char * GetDirEntry(void *dirp)
Get a directory entry. Returns 0 if no more entries.
Definition: TSystem.cxx:847
ClassImp(RooList) TObjOptLink *RooList TObjLink * link
Find the link corresponding to the named object in this list.
Definition: RooList.cxx:48
virtual int Unlink(const char *name)
Unlink, i.e. remove, a file.
Definition: TSystem.cxx:1346
Int_t Exec(const char *shellcmd)
Execute a command.
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:2334
void DispatchOneEvent(Bool_t pendingOnly=kFALSE)
Dispatch a single event.
Vc_ALWAYS_INLINE void free(T *p)
Frees memory that was allocated with Vc::malloc.
Definition: memory.h:94
virtual void Sleep(UInt_t milliSec)
Sleep milliSec milli seconds.
Definition: TSystem.cxx:441
Float_t fUser
Definition: TSystem.h:180
Bool_t IsValid() const
Definition: TInetAddress.h:80
void AddSignalHandler(TSignalHandler *sh)
Add a signal handler to list of system signal handlers.
Int_t fSwapFree
Definition: TSystem.h:196
static int UnixSend(int sock, const void *buf, int len, int flag)
Send exactly length bytes from buffer.
const char * PrependPathName(const char *dir, TString &name)
Concatenate a directory and a file name.
Int_t fMaxrfd
Definition: TSystem.h:273
Int_t SetFPEMask(Int_t mask=kDefaultMask)
Set which conditions trigger a floating point exception.
UChar_t mod R__LOCKGUARD2(gSrvAuthenticateMutex)
static const char * DynamicPath(const char *newpath=0, Bool_t reset=kFALSE)
Get shared library search path. Static utility function.
TObject * Next()
Return next object in collection.
Int_t fNfd
Signals that were trapped.
Definition: TSystem.h:272
R__EXTERN TFileHandler * gXDisplay
Definition: TSystem.h:550
TString fShell
Definition: TSystem.h:156
static TString * ReadString(TBuffer &b, const TClass *clReq)
Read TString object from buffer.
Definition: TString.cxx:1258
TString fRealName
Definition: TSystem.h:155
static int UnixSetitimer(Long_t ms)
Set interval timer to time-out in ms milliseconds.
virtual const char * Getenv(const char *env)
Get environment variable.
Definition: TSystem.cxx:1627
virtual void ListLibraries(const char *regexp="")
List all loaded shared libraries.
Definition: TSystem.cxx:2011
static void UnixResetSignals()
Restore old signal handlers.
FILE * OpenPipe(const char *shellcmd, const char *mode)
Open a pipe.
TString & Append(const char *cs)
Definition: TString.h:492
TInetAddress GetHostByName(const char *server)
Get Internet Protocol (IP) address of host.
int AcceptConnection(int sock)
Accept a connection.
Int_t Atoi() const
Return integer value of string.
Definition: TString.cxx:1964
virtual void Unload(const char *module)
Unload a shared library.
Definition: TSystem.cxx:1990
char * pw_name
Definition: TWinNTSystem.h:50
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition: TObject.cxx:918
virtual TInetAddress GetHostByName(const char *server)
Get Internet Protocol (IP) address of host.
Definition: TSystem.cxx:2245
int CopyFile(const char *from, const char *to, Bool_t overwrite=kFALSE)
Copy a file.
void ResetSignals()
Reset signals handlers to previous behaviour.
int SetSockOpt(int sock, int option, int val)
Set socket option.
Int_t fGid
Definition: TSystem.h:140
UInt_t GetAddress() const
Definition: TInetAddress.h:72
ELogLevel
Definition: TSystem.h:66
const Int_t kNFDBITS
TSeqCollection * fFileHandler
Definition: TSystem.h:288
A doubly linked list.
Definition: TList.h:47
Float_t fLoad1m
Definition: TSystem.h:177
TString & GetLastErrorString()
Return the thread local storage for the custom last error message.
Definition: TSystem.cxx:2048
char ** Argv() const
Definition: TApplication.h:142
static void SigHandler(ESignals sig)
Unix signal handler.
Int_t fL2Cache
Definition: TSystem.h:168
int GetFd() const
TTimer * RemoveTimer(TTimer *ti)
Remove timer from list of system timers.
virtual Bool_t WriteNotify()
Notify when something can be written to the descriptor associated with this handler.
R__EXTERN const char * gProgName
Definition: TSystem.h:234
int GetCpuInfo(CpuInfo_t *info, Int_t sampleTime=1000) const
Returns cpu load average and load info into the CpuInfo_t structure.
Float_t fCpuUser
Definition: TSystem.h:204
ESignals
char * pw_gecos
Definition: TWinNTSystem.h:55
static const char * UnixHomedirectory(const char *user=0)
Returns the user's home directory.
Bool_t IsActive() const
TString fUser
Definition: TSystem.h:152
static void sighandler(int sig)
Call the signal handler associated with the signal.
void FreeDirectory(void *dirp)
Close a Unix file system directory.
ClassImp(TUnixSystem) TUnixSystem
virtual void Setenv(const char *name, const char *value)
Set environment variable.
Definition: TSystem.cxx:1611
Int_t fCpus
Definition: TSystem.h:165
virtual Bool_t HasWriteInterest()
True if handler is interested in write events.
Bool_t EndsWith(const char *pat, ECaseCompare cmp=kExact) const
Return true if string ends with the specified string.
Definition: TString.cxx:2220
Double_t length(const TVector2 &v)
Definition: CsgOps.cxx:347
virtual Bool_t Init()
Initialize the OS interface.
Definition: TSystem.cxx:186
int Chmod(const char *file, UInt_t mode)
Set the file permission bits. Returns -1 in case or error, 0 otherwise.
Bool_t fIsLink
Definition: TSystem.h:143
R__EXTERN TSystem * gSystem
Definition: TSystem.h:549
void FillWithCwd(char *cwd) const
Fill buffer with current working directory.
int Utime(const char *file, Long_t modtime, Long_t actime)
Set a files modification and access times.
virtual Int_t GetValue(const char *name, Int_t dflt)
Returns the integer value for a resource.
Definition: TEnv.cxx:494
TInetAddress GetSockName(int sock)
Get Internet Protocol (IP) address of host and port #.
Int_t fSwapUsed
Definition: TSystem.h:195
Bool_t Gets(FILE *fp, Bool_t chop=kTRUE)
Read one line from the stream, including the , or until EOF.
Definition: Stringio.cxx:198
Long_t fMemVirtual
Definition: TSystem.h:207
#define HOWMANY(x, y)
virtual void SetReadReady()
std::string GetHomeDirectory(const char *userName=0) const
Return the user's home directory.
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:498
void CloseConnection(int sock, Bool_t force=kFALSE)
Close socket.
void Form(const char *fmt,...)
Formats a string using a printf style format descriptor.
Definition: TString.cxx:2321
void Closelog()
Close connection to system log daemon.
unsigned int UInt_t
Definition: RtypesCore.h:42
TMarker * m
Definition: textangle.C:8
char * Form(const char *fmt,...)
void SetDisplay()
Set DISPLAY environment variable based on utmp entry. Only for UNIX.
static const char * StripOffProto(const char *path, const char *proto)
Definition: TSystem.h:325
Definition: TSocket.h:68
Handles synchronous and a-synchronous timer events.
Definition: TTimer.h:57
Bool_t CheckTimer(const TTime &now)
Check if timer timed out.
Definition: TTimer.cxx:126
Float_t fLoad5m
Definition: TSystem.h:178
Bool_t CheckDescriptors()
Check if there is activity on some file descriptors and call their Notify() member.
TSubString Strip(EStripType s=kTrailing, char c= ' ') const
Return a substring of self stripped at beginning and/or end.
Definition: TString.cxx:1069
Func_t DynFindSymbol(const char *module, const char *entry)
dynamic linking of module
static int UnixWaitchild()
Wait till child is finished.
void * OpenDirectory(const char *name)
Open a Unix file system directory. Returns 0 if directory does not exist.
static int UnixUnixService(int port, int backlog)
Open a socket, bind to it and start listening for Unix domain connections to it.
static const char * UnixSigname(ESignals sig)
Return the signal name associated with a signal.
Bool_t IsNull() const
Definition: TString.h:387
Int_t RedirectOutput(const char *name, const char *mode="a", RedirectHandle_t *h=0)
Redirect standard output (stdout, stderr) to the specified file.
static int UnixFSstat(const char *path, Long_t *id, Long_t *bsize, Long_t *blocks, Long_t *bfree)
Get info about a file system: id, bsize, bfree, blocks.
Long64_t entry
TString & String()
Definition: TObjString.h:52
const char * GetDynamicPath()
Return the dynamic path (used to find shared libraries).
void AddAlias(const char *alias)
Add alias to list of aliases.
virtual void FreeDirectory(void *dirp)
Free a directory.
Definition: TSystem.cxx:839
virtual int ClosePipe(FILE *pipe)
Close the pipe.
Definition: TSystem.cxx:675
TGraphErrors * gr
Definition: legend1.C:25
TObjArray * Tokenize(const TString &delim) const
This function is used to isolate sequential tokens in a TString.
Definition: TString.cxx:2240
Int_t GetUid(const char *user=0)
Returns the user's id. If user = 0, returns current user's id.
#define Printf
Definition: TGeoToOCC.h:18
int GetProcInfo(ProcInfo_t *info) const
Returns cpu and memory used by this process into the ProcInfo_t structure.
void Unsetenv(const char *name)
Unset environment variable.
UserGroup_t * GetGroupInfo(Int_t gid)
Returns all group info in the UserGroup_t structure.
char * StrDup(const char *str)
Duplicate the string str.
Definition: TString.cxx:2513
virtual int SetSockOpt(int sock, int kind, int val)
Set socket option.
Definition: TSystem.cxx:2390
static void UnixSignal(ESignals sig, SigHandler_t h)
Set a signal handler for a signal.
static unsigned int total
TString & Remove(Ssiz_t pos)
Definition: TString.h:616
long Long_t
Definition: RtypesCore.h:50
int Ssiz_t
Definition: RtypesCore.h:63
TString fPasswd
Definition: TSystem.h:154
virtual void SysError(const char *method, const char *msgfmt,...) const
Issue system error message.
Definition: TObject.cxx:932
const char * Getenv(const char *name)
Get environment variable.
virtual TSignalHandler * RemoveSignalHandler(TSignalHandler *sh)
Remove a signal handler from list of signal handlers.
Definition: TSystem.cxx:546
static int UnixMakedir(const char *name)
Make a Unix file system directory.
virtual Int_t GetSize() const
Definition: TCollection.h:95
TFdSet * fReadready
Files that should be checked for write events.
Definition: TSystem.h:269
static int UnixUdpService(int port, int backlog)
Open a socket, bind to it and start listening for UDP connections on the port.
void AddAddress(UInt_t addr)
Add alternative address to list of addresses.
R__EXTERN const char * gProgPath
Definition: TSystem.h:235
TString & Swap(TString &other)
Definition: TString.h:647
#define STRUCT_UTMP
Float_t fCpuSys
Definition: TSystem.h:205
Int_t GetEffectiveUid()
Returns the effective user id.
static int UnixUnixConnect(int port)
Connect to a Unix domain socket.
virtual Func_t DynFindSymbol(const char *module, const char *entry)
Find specific entry point in specified library.
Definition: TSystem.cxx:1982
virtual const char * GetName() const
Returns name of object.
Definition: TObject.cxx:415
static int UnixTcpService(int port, Bool_t reuse, int backlog, int tcpwindowsize)
Open a socket, bind to it and start listening for TCP/IP connections on the port. ...
double Double_t
Definition: RtypesCore.h:55
TFdSet * fReadmask
Definition: TSystem.h:267
int RecvRaw(int sock, void *buffer, int length, int flag)
Receive exactly length bytes into buffer.
Long64_t Atoll() const
Return long long value of string.
Definition: TString.cxx:1990
int RecvBuf(int sock, void *buffer, int length)
Receive a buffer headed by a length indicator.
ELogFacility
Definition: TSystem.h:77
Int_t GetFamily() const
Definition: TInetAddress.h:76
int Rename(const char *from, const char *to)
Rename a file. Returns 0 when successful, -1 in case of failure.
int AnnounceTcpService(int port, Bool_t reuse, int backlog, int tcpwindowsize=-1)
Announce TCP/IP service.
int type
Definition: TGX11.cxx:120
R__EXTERN TEnv * gEnv
Definition: TEnv.h:174
virtual const char * ExpandFileName(const char *fname)
Expand a pathname getting rid of special shell characters like ~.
Definition: TSystem.cxx:1071
void CheckChilds()
Check if children have finished.
TString fCpuType
Definition: TSystem.h:164
unsigned long ULong_t
Definition: RtypesCore.h:51
double func(double *x, double *p)
Definition: stressTF1.cxx:213
static void UnixIgnoreSignal(ESignals sig, Bool_t ignore)
If ignore is true ignore the specified signal, else restore previous behaviour.
TFdSet * fSignals
Files with writes waiting.
Definition: TSystem.h:271
#define R__LOCKGUARD(mutex)
Bool_t IsSync() const
Definition: TTimer.h:86
static void * UnixOpendir(const char *name)
Open a directory.
Definition: TSocket.h:67
EAccessMode
Definition: TSystem.h:54
void Reset()
Definition: TSystem.h:223
Bool_t ChangeDirectory(const char *path)
Change directory. Returns kTRUE in case of success, kFALSE otherwise.
const char * GetLinkedLibraries()
Get list of shared libraries loaded at the start of the executable.
#define name(a, b)
Definition: linkTestLib0.cpp:5
char * GetServiceByPort(int port)
Get name of internet service.
Binding & operator=(OUT(*fun)(void))
Int_t fMemTotal
Definition: TSystem.h:191
int pw_gid
Definition: TWinNTSystem.h:53
#define org(otri, vertexptr)
Definition: triangle.c:1037
int EscChar(const char *src, char *dst, int dstlen, char *specchars, char escchar)
Escape specchars in src with escchar and copy to dst.
Definition: TString.cxx:2548
virtual void HandleException(Int_t sig)
Handle exceptions (kSigBus, kSigSegmentationViolation, kSigIllegalInstruction and kSigFloatingExcepti...
typedef void((*Func_t)())
Int_t fMaxwfd
Definition: TSystem.h:274
TSeqCollection * fTimers
Definition: TSystem.h:286
void ResetSignal(ESignals sig, Bool_t reset=kTRUE)
If reset is true reset the signal handler for the specified signal to the default handler...
void IgnoreSignal(ESignals sig, Bool_t ignore=kTRUE)
If ignore is true ignore the specified signal, else restore previous behaviour.
const Ssiz_t kNPOS
Definition: Rtypes.h:115
virtual void AddTimer(TTimer *t)
Add timer to list of system timers.
Definition: TSystem.cxx:475
static const char * UnixGetdirentry(void *dir)
Returns the next directory entry.
R__EXTERN const char * gRootDir
Definition: TSystem.h:233
void ResetTimer(TTimer *ti)
Reset a-sync timer.
void AddDynamicPath(const char *lib)
Add a new directory to the dynamic path.
Short_t Max(Short_t a, Short_t b)
Definition: TMathBase.h:202
ESignals GetSignal() const
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition: TString.h:567
const char * GetDirEntry(void *dirp)
Get next Unix file system directory entry. Returns 0 if no more entries.
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...
Int_t fMemUsed
Definition: TSystem.h:192
Int_t fCpuSpeed
Definition: TSystem.h:166
TInetAddress GetPeerName(int sock)
Get Internet Protocol (IP) address of remote host and port #.
void AddFileHandler(TFileHandler *fh)
Add a file handler to the list of system file handlers.
#define NULL
Definition: Rtypes.h:82
Long_t fIno
Definition: TSystem.h:137
FILE * TempFileName(TString &base, const char *dir=0)
Create a secure temporary file by appending a unique 6 letter string to base.
char * pw_passwd
Definition: TWinNTSystem.h:51
char * pw_dir
Definition: TWinNTSystem.h:56
virtual void * OpenDirectory(const char *name)
Open a directory. Returns 0 if directory does not exist.
Definition: TSystem.cxx:830
R__EXTERN Int_t gDebug
Definition: Rtypes.h:128
Iterator of ordered collection.
TSignalHandler * RemoveSignalHandler(TSignalHandler *sh)
Remove a signal handler from list of signal handlers.
int AnnounceUnixService(int port, int backlog)
Announce unix domain service on path "kServerPath/".
virtual Bool_t ReadNotify()
Notify when something can be read from the descriptor associated with this handler.
int ClosePipe(FILE *pipe)
Close the pipe.
void SetDynamicPath(const char *lib)
Set the dynamic path to a new value.
int Link(const char *from, const char *to)
Create a link from file1 to file2.
void Abort(int code=0)
Abort the application.
void Unload(const char *module)
Unload a shared library.
TSystem * FindHelper(const char *path, void *dirptr=0)
Create helper TSystem to handle file and directory operations that might be special for remote file a...
Definition: TSystem.cxx:748
virtual void AddFileHandler(TFileHandler *fh)
Add a file handler to the list of system file handlers.
Definition: TSystem.cxx:558
static void ResetErrno()
Static function resetting system error number.
Definition: TSystem.cxx:280
void SigAlarmInterruptsSyscalls(Bool_t set)
When the argument is true the SIGALRM signal handler is set so that interrupted syscalls will not be ...
Int_t GetEffectiveGid()
Returns the effective group id.
double result[121]
Float_t fTotal
Definition: TSystem.h:182
Bool_t CheckSignals(Bool_t sync)
Check if some signals were raised and call their Notify() member.
static int UnixUdpConnect(const char *hostname, int port)
Creates a UDP socket connection Is called via the TSocket constructor.
int GetServiceByName(const char *service)
Get port # of internet service.
virtual Bool_t ExpandPathName(TString &path)
Expand a pathname getting rid of special shell characters like ~.
Definition: TSystem.cxx:1243
TTime Now()
Get current time in milliseconds since 0:00 Jan 1 1995.
TFdSet * fWriteready
Files with reads waiting.
Definition: TSystem.h:270
Int_t fSwapTotal
Definition: TSystem.h:194
TObject * At(Int_t idx) const
Definition: TObjArray.h:167
string message
Definition: ROOT.py:94
void Openlog(const char *name, Int_t options, ELogFacility facility)
Open connection to system log daemon.
R__EXTERN TInterpreter * gCling
Definition: TInterpreter.h:504
Long_t fDev
Definition: TSystem.h:136
Ssiz_t Index(const char *pat, Ssiz_t i=0, ECaseCompare cmp=kExact) const
Definition: TString.h:582
virtual const char * GetSTLIncludePath() const
Definition: TInterpreter.h:137
UserGroup_t * GetUserInfo(Int_t uid)
Returns all user info in the UserGroup_t structure.
Abstract base class defining a generic interface to the underlying Operating System.
Definition: TSystem.h:258
const Bool_t kTRUE
Definition: Rtypes.h:91
#define PATH_MAX
Definition: civetweb.c:371
float * q
Definition: THbookFile.cxx:87
Int_t fStdErrDup
Definition: TSystem.h:219
Ordered collection.
void DispatchSignals(ESignals sig)
Handle and dispatch signals.
int SendBuf(int sock, const void *buffer, int length)
Send a buffer headed by a length indicator.
float value
Definition: math.cpp:443
TFdSet * fWritemask
Files that should be checked for read events.
Definition: TSystem.h:268
Vc_ALWAYS_INLINE_L T *Vc_ALWAYS_INLINE_R malloc(size_t n)
Allocates memory on the Heap with alignment and padding suitable for vectorized access.
Definition: memory.h:67
virtual char * ConcatFileName(const char *dir, const char *name)
Concatenate a directory and a file name. User must delete returned string.
Definition: TSystem.cxx:1044
void ListLibraries(const char *regexp="")
List all loaded shared libraries.
Float_t fIdle
Definition: TSystem.h:183
const char * WorkingDirectory()
Return working directory.
const Int_t n
Definition: legend1.C:16
TString fFile
Definition: TSystem.h:215
int Load(const char *module, const char *entry="", Bool_t system=kFALSE)
Load a shared library.
Long_t fMemResident
Definition: TSystem.h:206
Bool_t IsAsync() const
Definition: TTimer.h:87
void Setenv(const char *name, const char *value)
Set environment variable.
int OpenConnection(const char *server, int port, int tcpwindowsize=-1, const char *protocol="tcp")
Open a connection to a service on a server.
virtual Bool_t HasReadInterest()
True if handler is interested in read events.
int AnnounceUdpService(int port, int backlog)
Announce UDP service.
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition: TObject.cxx:904