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