20 #include "RConfigure.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)
59 #if defined(ULTRIX) || defined(R__SUN)
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>
67 #if defined(R__AIX) || defined(R__SOLARIS)
68 # include <sys/select.h>
70 #if defined(R__MACOSX)
71 # include <mach-o/dyld.h>
72 # include <sys/mount.h>
73 extern "C" int statfs(
const char *file,
struct statfs *buffer);
74 #elif defined(R__LINUX) || defined(R__HURD)
76 #elif defined(R__FBSD) || defined(R__OBSD)
77 # include <sys/param.h>
78 # include <sys/mount.h>
80 # include <sys/statfs.h>
88 #include <sys/param.h>
92 #include <sys/resource.h>
97 #include <sys/socket.h>
98 #include <netinet/in.h>
99 #include <netinet/tcp.h>
101 # define _XOPEN_EXTENDED_SOURCE
102 # include <arpa/inet.h>
103 # undef _XOPEN_EXTENDED_SOURCE
104 # if !defined(_AIX41) && !defined(_AIX43)
106 # define HASNOT_INETATON
109 # include <arpa/inet.h>
114 #if defined(R__SOLARIS)
115 # include <sys/systeminfo.h>
116 # include <sys/filio.h>
117 # include <sys/sockio.h>
118 # define HASNOT_INETATON
120 # define INADDR_NONE (UInt_t)-1
124 #if defined(R__SOLARIS)
125 # define HAVE_UTMPX_H
126 # define UTMP_NO_ADDR
129 #if defined(MAC_OS_X_VERSION_10_5)
130 # define HAVE_UTMPX_H
131 # define UTMP_NO_ADDR
135 # include <sys/param.h>
136 # if __FreeBSD_version >= 900007
137 # define HAVE_UTMPX_H
141 #if defined(R__AIX) || defined(R__FBSD) || \
142 defined(R__OBSD) || defined(R__LYNXOS) || \
143 (defined(R__MACOSX) && !defined(MAC_OS_X_VERSION_10_5))
144 # define UTMP_NO_ADDR
147 #if (defined(R__AIX) && !defined(_AIX43)) || \
148 (defined(R__SUNGCC3) && !defined(__arch64__))
150 #elif defined(R__GLIBC) || defined(R__FBSD) || \
151 (defined(R__SUNGCC3) && defined(__arch64__)) || \
152 defined(R__OBSD) || defined(MAC_OS_X_VERSION_10_4) || \
153 (defined(R__AIX) && defined(_AIX43)) || \
154 (defined(R__SOLARIS) && defined(_SOCKLEN_T))
155 # define USE_SOCKLEN_T
158 #if defined(R__LYNXOS)
160 extern int putenv(
const char *);
161 extern int inet_aton(
const char *,
struct in_addr *);
167 #define STRUCT_UTMP struct utmpx
170 #define STRUCT_UTMP struct utmp
172 #if !defined(UTMP_FILE) && defined(_PATH_UTMP) // 4.4BSD
173 #define UTMP_FILE _PATH_UTMP
175 #if defined(UTMPX_FILE) // Solaris, SysVr4
177 #define UTMP_FILE UTMPX_FILE
180 #define UTMP_FILE "/etc/utmp"
184 #if (defined(R__LINUX) || defined(R__HURD)) && !defined(R__WINGCC)
185 # if __GLIBC__ == 2 && __GLIBC_MINOR__ >= 1
186 # define HAVE_BACKTRACE_SYMBOLS_FD
190 #if defined(R__MACOSX)
191 # define HAVE_BACKTRACE_SYMBOLS_FD
195 #ifdef HAVE_BACKTRACE_SYMBOLS_FD
196 # include <execinfo.h>
205 #ifdef HAVE_BACKTRACE_SYMBOLS_FD
208 static const int kMAX_BACKTRACE_DEPTH = 128;
212 #if (defined(R__LINUX) && !defined(R__WINGCC))
213 #include <fpu_control.h>
215 #include <sys/prctl.h>
218 #if defined(R__MACOSX) && defined(__SSE2__)
219 #include <xmmintrin.h>
222 #if defined(R__MACOSX) && !defined(__SSE2__) && !defined(__xlC__) && \
223 !defined(__i386__) && !defined(__x86_64__) && !defined(__arm__) && \
227 #include <ucontext.h>
230 #include <mach/thread_status.h>
232 #define fegetenvd(x) asm volatile("mffs %0" : "=f" (x));
233 #define fesetenvd(x) asm volatile("mtfsf 255,%0" : : "f" (x));
236 FE_ENABLE_INEXACT = 0x00000008,
237 FE_ENABLE_DIVBYZERO = 0x00000010,
238 FE_ENABLE_UNDERFLOW = 0x00000020,
239 FE_ENABLE_OVERFLOW = 0x00000040,
240 FE_ENABLE_INVALID = 0x00000080,
241 FE_ENABLE_ALL_EXCEPT = 0x000000F8
245 #if defined(R__MACOSX) && !defined(__SSE2__) && \
246 (defined(__i386__) || defined(__x86_64__) || defined(__arm__) || defined(__arm64__))
258 template<typename U = T, typename std::enable_if<std::is_member_pointer<decltype(&U::ut_name)>::value,
int>::type = 0>
259 static char getValue(U* ue,
int) {
260 return ue->ut_name[0];
263 template<typename U = T, typename std::enable_if<std::is_member_pointer<decltype(&U::ut_user)>::value,
int>::type = 0>
264 static char getValue(U* ue,
long) {
265 return ue->ut_user[0];
269 static char get_ut_name(STRUCT_UTMP *ue) {
271 return ut_name<STRUCT_UTMP>::getValue(ue, 0);
275 struct TUtmpContent {
276 STRUCT_UTMP *fUtmpContents;
279 TUtmpContent() : fUtmpContents(0), fEntries(0) {}
280 ~TUtmpContent() { free(fUtmpContents); }
282 STRUCT_UTMP *SearchUtmpEntry(
const char *tty)
286 STRUCT_UTMP *ue = fUtmpContents;
290 if (get_ut_name(ue) && !strncmp(tty, ue->ut_line,
sizeof(ue->ut_line)))
302 struct stat file_stats;
307 R__LOCKGUARD2(gSystemMutex);
309 utmp = fopen(UTMP_FILE,
"r");
313 if (fstat(fileno(utmp), &file_stats) == -1) {
317 size = file_stats.st_size;
323 fUtmpContents = (STRUCT_UTMP *) malloc(size);
324 if (!fUtmpContents) {
329 n_read = fread(fUtmpContents, 1, size, utmp);
331 if (fclose(utmp) != EOF && n_read == size) {
332 fEntries = size /
sizeof(STRUCT_UTMP);
345 const char *kServerPath =
"/tmp";
346 const char *kProtocolName =
"tcp";
350 # define HOWMANY(x, y) (((x)+((y)-1))/(y))
353 const Int_t kNFDBITS = (
sizeof(Long_t) * 8);
355 const Int_t kFDSETSIZE = FD_SETSIZE;
357 const Int_t kFDSETSIZE = 256;
363 ULong_t fds_bits[HOWMANY(kFDSETSIZE, kNFDBITS)];
365 TFdSet() { memset(fds_bits, 0,
sizeof(fds_bits)); }
366 TFdSet(
const TFdSet &org) { memcpy(fds_bits, org.fds_bits,
sizeof(org.fds_bits)); }
367 TFdSet &operator=(
const TFdSet &rhs) {
if (
this != &rhs) { memcpy(fds_bits, rhs.fds_bits,
sizeof(rhs.fds_bits));}
return *
this; }
368 void Zero() { memset(fds_bits, 0,
sizeof(fds_bits)); }
371 if (n >= 0 && n < kFDSETSIZE) {
372 fds_bits[n/kNFDBITS] |= (1UL << (n % kNFDBITS));
374 ::Fatal(
"TFdSet::Set",
"fd (%d) out of range [0..%d]", n, kFDSETSIZE-1);
379 if (n >= 0 && n < kFDSETSIZE) {
380 fds_bits[n/kNFDBITS] &= ~(1UL << (n % kNFDBITS));
382 ::Fatal(
"TFdSet::Clr",
"fd (%d) out of range [0..%d]", n, kFDSETSIZE-1);
387 if (n >= 0 && n < kFDSETSIZE) {
388 return (fds_bits[n/kNFDBITS] & (1UL << (n % kNFDBITS))) != 0;
390 ::Fatal(
"TFdSet::IsSet",
"fd (%d) out of range [0..%d]", n, kFDSETSIZE-1);
394 ULong_t *GetBits() {
return (ULong_t *)fds_bits; }
400 static void SigHandler(ESignals sig)
403 ((TUnixSystem*)gSystem)->DispatchSignals(sig);
408 static const char *GetExePath()
410 TTHREAD_TLS_DECL(TString,exepath);
412 #if defined(R__MACOSX)
413 exepath = _dyld_get_image_name(0);
414 #elif defined(R__LINUX) || defined(R__SOLARIS) || defined(R__FBSD)
415 char buf[kMAXPATHLEN];
418 #if defined(R__LINUX)
419 int ret = readlink(
"/proc/self/exe", buf, kMAXPATHLEN);
420 #elif defined(R__SOLARIS)
421 int ret = readlink(
"/proc/self/path/a.out", buf, kMAXPATHLEN);
422 #elif defined(R__FBSD)
423 int ret = readlink(
"/proc/curproc/file", buf, kMAXPATHLEN);
425 if (ret > 0 && ret < kMAXPATHLEN) {
432 TString p = gApplication->Argv(0);
433 if (p.BeginsWith(
"/"))
435 else if (p.Contains(
"/")) {
436 exepath = gSystem->WorkingDirectory();
440 char *exe = gSystem->Which(gSystem->Getenv(
"PATH"), p, kExecutePermission);
451 #if defined(HAVE_DLADDR) && !defined(R__MACOSX)
454 static void SetRootSys()
457 if (gSystem->Getenv(
"ROOTIGNOREPREFIX")) {
459 void *addr = (
void *)SetRootSys;
461 if (dladdr(addr, &info) && info.dli_fname && info.dli_fname[0]) {
462 char respath[kMAXPATHLEN];
463 if (!realpath(info.dli_fname, respath)) {
464 if (!gSystem->Getenv(
"ROOTSYS"))
465 ::SysError(
"TUnixSystem::SetRootSys",
"error getting realpath of libCore, please set ROOTSYS in the shell");
467 TString rs = gSystem->DirName(respath);
468 gSystem->Setenv(
"ROOTSYS", gSystem->DirName(rs));
477 #if defined(R__MACOSX)
478 static TString gLinkedDylibs;
482 static void DylibAdded(
const struct mach_header *mh, intptr_t )
485 static Bool_t gotFirstSo = kFALSE;
486 static TString linkedDylibs;
491 gLinkedDylibs = linkedDylibs;
495 TString lib = _dyld_get_image_name(i++);
497 TRegexp sovers =
"libCore\\.[0-9]+\\.*[0-9]*\\.*[0-9]*\\.so";
498 TRegexp dyvers =
"libCore\\.[0-9]+\\.*[0-9]*\\.*[0-9]*\\.dylib";
501 if (gSystem->Getenv(
"ROOTIGNOREPREFIX")) {
503 if (lib.EndsWith(
"libCore.dylib") || lib.EndsWith(
"libCore.so") ||
504 lib.Index(sovers) != kNPOS || lib.Index(dyvers) != kNPOS) {
505 char respath[kMAXPATHLEN];
506 if (!realpath(lib, respath)) {
507 if (!gSystem->Getenv(
"ROOTSYS"))
508 ::SysError(
"TUnixSystem::DylibAdded",
"error getting realpath of libCore, please set ROOTSYS in the shell");
510 TString rs = gSystem->DirName(respath);
511 gSystem->Setenv(
"ROOTSYS", gSystem->DirName(rs));
522 if (lib.EndsWith(
"/libSystem.B.dylib"))
526 if (!gotFirstSo && (lib.EndsWith(
".dylib") || lib.EndsWith(
".so"))) {
527 sovers =
"\\.[0-9]+\\.*[0-9]*\\.so";
528 Ssiz_t idx = lib.Index(sovers);
533 dyvers =
"\\.[0-9]+\\.*[0-9]*\\.dylib";
534 idx = lib.Index(dyvers);
539 if (!gSystem->AccessPathName(lib, kReadPermission)) {
540 if (linkedDylibs.Length())
548 ClassImp(TUnixSystem);
552 TUnixSystem::TUnixSystem() : TSystem(
"Unix",
"Unix System")
558 TUnixSystem::~TUnixSystem()
572 Bool_t TUnixSystem::Init()
577 fReadmask =
new TFdSet;
578 fWritemask =
new TFdSet;
579 fReadready =
new TFdSet;
580 fWriteready =
new TFdSet;
581 fSignals =
new TFdSet;
584 UnixSignal(kSigChild, SigHandler);
585 UnixSignal(kSigBus, SigHandler);
586 UnixSignal(kSigSegmentationViolation, SigHandler);
587 UnixSignal(kSigIllegalInstruction, SigHandler);
588 UnixSignal(kSigSystem, SigHandler);
589 UnixSignal(kSigAlarm, SigHandler);
590 UnixSignal(kSigUrgent, SigHandler);
591 UnixSignal(kSigFloatingException, SigHandler);
592 UnixSignal(kSigWindowChanged, SigHandler);
593 UnixSignal(kSigUser2, SigHandler);
595 #if defined(R__MACOSX)
598 _dyld_register_func_for_add_image(DylibAdded);
599 #elif defined(HAVE_DLADDR)
604 gRootDir = ROOT::FoundationUtils::GetFallbackRootSys().c_str();
617 void TUnixSystem::SetProgname(
const char *name)
624 if (!name || !*name) {
626 gProgName = StrDup(BaseName(name));
627 gProgPath = StrDup(DirName(name));
629 gProgName = StrDup(BaseName(name));
630 char *w = Which(Getenv(
"PATH"), gProgName);
631 gProgPath = StrDup(DirName(w));
639 void TUnixSystem::SetDisplay()
641 if (!Getenv(
"DISPLAY")) {
642 char *tty = ::ttyname(0);
649 STRUCT_UTMP *utmp_entry = utmp.SearchUtmpEntry(tty);
651 if (utmp_entry->ut_host[0]) {
652 if (strchr(utmp_entry->ut_host,
':')) {
653 Setenv(
"DISPLAY", utmp_entry->ut_host);
654 Warning(
"SetDisplay",
"DISPLAY not set, setting it to %s",
655 utmp_entry->ut_host);
658 snprintf(disp,
sizeof(disp),
"%s:0.0", utmp_entry->ut_host);
659 Setenv(
"DISPLAY", disp);
660 Warning(
"SetDisplay",
"DISPLAY not set, setting it to %s",
665 else if (utmp_entry->ut_addr) {
667 struct sockaddr_in addr;
668 addr.sin_family = AF_INET;
670 memcpy(&addr.sin_addr, &utmp_entry->ut_addr,
sizeof(addr.sin_addr));
671 memset(&addr.sin_zero[0], 0,
sizeof(addr.sin_zero));
672 struct sockaddr *sa = (
struct sockaddr *) &addr;
674 char hbuf[NI_MAXHOST + 4];
675 if (getnameinfo(sa,
sizeof(
struct sockaddr), hbuf,
sizeof(hbuf),
nullptr, 0, NI_NAMEREQD) == 0) {
676 assert( strlen(hbuf) < NI_MAXHOST );
677 strcat(hbuf,
":0.0");
678 Setenv(
"DISPLAY", hbuf);
679 Warning(
"SetDisplay",
"DISPLAY not set, setting it to %s",
687 if (!gROOT->IsBatch() && !getenv(
"DISPLAY")) {
688 Error(
"SetDisplay",
"Can't figure out DISPLAY, set it manually\n"
689 "In case you run a remote ssh session, restart your ssh session with:\n"
690 "=========> ssh -Y");
699 const char *TUnixSystem::GetError()
701 Int_t err = GetErrno();
702 if (err == 0 && GetLastErrorString() !=
"")
703 return GetLastErrorString();
705 #if defined(R__SOLARIS) || defined (R__LINUX) || defined(R__AIX) || \
706 defined(R__FBSD) || defined(R__OBSD) || defined(R__HURD)
707 return strerror(err);
709 if (err < 0 || err >= sys_nerr)
710 return Form(
"errno out of range %d", err);
711 return sys_errlist[err];
718 const char *TUnixSystem::HostName()
720 if (fHostname ==
"") {
722 #if defined(R__SOLARIS)
723 sysinfo(SI_HOSTNAME, hn,
sizeof(hn));
725 gethostname(hn,
sizeof(hn));
729 return (
const char *)fHostname;
738 void TUnixSystem::AddFileHandler(TFileHandler *h)
740 R__LOCKGUARD2(gSystemMutex);
742 TSystem::AddFileHandler(h);
745 if (h->HasReadInterest()) {
747 fMaxrfd = TMath::Max(fMaxrfd, fd);
749 if (h->HasWriteInterest()) {
751 fMaxwfd = TMath::Max(fMaxwfd, fd);
760 TFileHandler *TUnixSystem::RemoveFileHandler(TFileHandler *h)
764 R__LOCKGUARD2(gSystemMutex);
766 TFileHandler *oh = TSystem::RemoveFileHandler(h);
769 TIter next(fFileHandler);
774 while ((th = (TFileHandler *) next())) {
775 int fd = th->GetFd();
776 if (th->HasReadInterest()) {
778 fMaxrfd = TMath::Max(fMaxrfd, fd);
780 if (th->HasWriteInterest()) {
782 fMaxwfd = TMath::Max(fMaxwfd, fd);
793 void TUnixSystem::AddSignalHandler(TSignalHandler *h)
795 R__LOCKGUARD2(gSystemMutex);
797 TSystem::AddSignalHandler(h);
798 UnixSignal(h->GetSignal(), SigHandler);
805 TSignalHandler *TUnixSystem::RemoveSignalHandler(TSignalHandler *h)
809 R__LOCKGUARD2(gSystemMutex);
811 TSignalHandler *oh = TSystem::RemoveSignalHandler(h);
815 TIter next(fSignalHandler);
817 while ((hs = (TSignalHandler*) next())) {
818 if (hs->GetSignal() == h->GetSignal())
822 ResetSignal(h->GetSignal(), kTRUE);
831 void TUnixSystem::ResetSignal(ESignals sig, Bool_t reset)
834 UnixResetSignal(sig);
836 UnixSignal(sig, SigHandler);
842 void TUnixSystem::ResetSignals()
851 void TUnixSystem::IgnoreSignal(ESignals sig, Bool_t ignore)
853 UnixIgnoreSignal(sig, ignore);
864 void TUnixSystem::SigAlarmInterruptsSyscalls(Bool_t set)
866 UnixSigAlarmInterruptsSyscalls(set);
872 Int_t TUnixSystem::GetFPEMask()
876 #if defined(R__LINUX) && !defined(__powerpc__)
877 #if defined(__GLIBC__) && (__GLIBC__>2 || __GLIBC__==2 && __GLIBC_MINOR__>=1)
879 #if __GLIBC_MINOR__>=3
881 Int_t oldmask = fegetexcept();
888 Int_t oldmask = ~oldenv;
890 Int_t oldmask = ~oldenv.__control_word;
894 if (oldmask & FE_INVALID ) mask |= kInvalid;
895 if (oldmask & FE_DIVBYZERO) mask |= kDivByZero;
896 if (oldmask & FE_OVERFLOW ) mask |= kOverflow;
897 if (oldmask & FE_UNDERFLOW) mask |= kUnderflow;
899 if (oldmask & FE_INEXACT ) mask |= kInexact;
904 #if defined(R__MACOSX) && defined(__SSE2__)
906 Int_t oldmask = ~_MM_GET_EXCEPTION_MASK();
908 if (oldmask & _MM_MASK_INVALID ) mask |= kInvalid;
909 if (oldmask & _MM_MASK_DIV_ZERO ) mask |= kDivByZero;
910 if (oldmask & _MM_MASK_OVERFLOW ) mask |= kOverflow;
911 if (oldmask & _MM_MASK_UNDERFLOW) mask |= kUnderflow;
912 if (oldmask & _MM_MASK_INEXACT ) mask |= kInexact;
915 #if defined(R__MACOSX) && !defined(__SSE2__) && \
916 (defined(__i386__) || defined(__x86_64__) || defined(__arm__) || defined(__arm64__))
921 Int_t oldmask = ~oldenv.__fpscr;
922 #elif defined(__arm64__)
923 Int_t oldmask = ~oldenv.__fpcr;
925 Int_t oldmask = ~oldenv.__control;
928 if (oldmask & FE_INVALID ) mask |= kInvalid;
929 if (oldmask & FE_DIVBYZERO) mask |= kDivByZero;
930 if (oldmask & FE_OVERFLOW ) mask |= kOverflow;
931 if (oldmask & FE_UNDERFLOW) mask |= kUnderflow;
932 if (oldmask & FE_INEXACT ) mask |= kInexact;
935 #if defined(R__MACOSX) && !defined(__SSE2__) && !defined(__xlC__) && \
936 !defined(__i386__) && !defined(__x86_64__) && !defined(__arm__) && \
941 if (oldmask & FE_ENABLE_INVALID ) mask |= kInvalid;
942 if (oldmask & FE_ENABLE_DIVBYZERO) mask |= kDivByZero;
943 if (oldmask & FE_ENABLE_OVERFLOW ) mask |= kOverflow;
944 if (oldmask & FE_ENABLE_UNDERFLOW) mask |= kUnderflow;
945 if (oldmask & FE_ENABLE_INEXACT ) mask |= kInexact;
955 Int_t TUnixSystem::SetFPEMask(Int_t mask)
959 Int_t old = GetFPEMask();
961 #if defined(R__LINUX) && !defined(__powerpc__)
962 #if defined(__GLIBC__) && (__GLIBC__>2 || __GLIBC__==2 && __GLIBC_MINOR__>=1)
964 if (mask & kInvalid ) newm |= FE_INVALID;
965 if (mask & kDivByZero) newm |= FE_DIVBYZERO;
966 if (mask & kOverflow ) newm |= FE_OVERFLOW;
967 if (mask & kUnderflow) newm |= FE_UNDERFLOW;
969 if (mask & kInexact ) newm |= FE_INEXACT;
972 #if __GLIBC_MINOR__>=3
975 feclearexcept(FE_ALL_EXCEPT);
976 fedisableexcept(FE_ALL_EXCEPT);
977 feenableexcept(newm);
986 cur.__control_word &= ~newm;
994 #if defined(R__MACOSX) && defined(__SSE2__)
997 if (mask & kInvalid ) newm |= _MM_MASK_INVALID;
998 if (mask & kDivByZero) newm |= _MM_MASK_DIV_ZERO;
999 if (mask & kOverflow ) newm |= _MM_MASK_OVERFLOW;
1000 if (mask & kUnderflow) newm |= _MM_MASK_UNDERFLOW;
1001 if (mask & kInexact ) newm |= _MM_MASK_INEXACT;
1003 _MM_SET_EXCEPTION_MASK(_MM_GET_EXCEPTION_MASK() & ~newm);
1006 #if defined(R__MACOSX) && !defined(__SSE2__) && \
1007 (defined(__i386__) || defined(__x86_64__) || defined(__arm__) || defined(__arm64__))
1009 if (mask & kInvalid ) newm |= FE_INVALID;
1010 if (mask & kDivByZero) newm |= FE_DIVBYZERO;
1011 if (mask & kOverflow ) newm |= FE_OVERFLOW;
1012 if (mask & kUnderflow) newm |= FE_UNDERFLOW;
1013 if (mask & kInexact ) newm |= FE_INEXACT;
1017 #if defined(__arm__)
1018 cur.__fpscr &= ~newm;
1019 #elif defined(__arm64__)
1020 cur.__fpcr &= ~newm;
1022 cur.__control &= ~newm;
1027 #if defined(R__MACOSX) && !defined(__SSE2__) && !defined(__xlC__) && \
1028 !defined(__i386__) && !defined(__x86_64__) && !defined(__arm__) && \
1031 if (mask & kInvalid ) newm |= FE_ENABLE_INVALID;
1032 if (mask & kDivByZero) newm |= FE_ENABLE_DIVBYZERO;
1033 if (mask & kOverflow ) newm |= FE_ENABLE_OVERFLOW;
1034 if (mask & kUnderflow) newm |= FE_ENABLE_UNDERFLOW;
1035 if (mask & kInexact ) newm |= FE_ENABLE_INEXACT;
1039 curmask = (curmask & ~FE_ENABLE_ALL_EXCEPT) | newm;
1049 void TUnixSystem::DispatchOneEvent(Bool_t pendingOnly)
1051 Bool_t pollOnce = pendingOnly;
1055 if (gXDisplay && gXDisplay->Notify()) {
1056 if (fReadready->IsSet(gXDisplay->GetFd())) {
1057 fReadready->Clr(gXDisplay->GetFd());
1060 if (!pendingOnly)
return;
1064 if (fNfd > 0 && fFileHandler && fFileHandler->GetSize() > 0)
1065 if (CheckDescriptors())
1066 if (!pendingOnly)
return;
1069 fWriteready->Zero();
1071 if (pendingOnly && !pollOnce)
1075 if (fSigcnt > 0 && fSignalHandler->GetSize() > 0)
1076 if (CheckSignals(kTRUE))
1077 if (!pendingOnly)
return;
1083 if (fTimers && fTimers->GetSize() > 0)
1084 if (DispatchTimers(kTRUE)) {
1086 nextto = NextTimeOut(kTRUE);
1087 if (nextto > kItimerResolution || nextto == -1)
1092 nextto = NextTimeOut(kTRUE);
1094 if (fFileHandler && fFileHandler->GetSize() == 0)
1101 *fReadready = *fReadmask;
1102 *fWriteready = *fWritemask;
1104 int mxfd = TMath::Max(fMaxrfd, fMaxwfd);
1108 if (mxfd == 0 && nextto == -1)
1111 fNfd = UnixSelect(mxfd, fReadready, fWriteready, nextto);
1112 if (fNfd < 0 && fNfd != -2) {
1115 for (fd = 0; fd < mxfd; fd++) {
1117 if (fReadmask->IsSet(fd)) {
1118 rc = UnixSelect(fd+1, &t, 0, 0);
1119 if (rc < 0 && rc != -2) {
1120 SysError(
"DispatchOneEvent",
"select: read error on %d", fd);
1124 if (fWritemask->IsSet(fd)) {
1125 rc = UnixSelect(fd+1, 0, &t, 0);
1126 if (rc < 0 && rc != -2) {
1127 SysError(
"DispatchOneEvent",
"select: write error on %d", fd);
1128 fWritemask->Clr(fd);
1140 void TUnixSystem::Sleep(UInt_t milliSec)
1144 tv.tv_sec = milliSec / 1000;
1145 tv.tv_usec = (milliSec % 1000) * 1000;
1147 select(0, 0, 0, 0, &tv);
1158 Int_t TUnixSystem::Select(TList *act, Long_t to)
1165 TFileHandler *h = 0;
1166 while ((h = (TFileHandler *) next())) {
1167 Int_t fd = h->GetFd();
1169 if (h->HasReadInterest()) {
1171 mxfd = TMath::Max(mxfd, fd);
1173 if (h->HasWriteInterest()) {
1175 mxfd = TMath::Max(mxfd, fd);
1177 h->ResetReadyMask();
1181 rc = UnixSelect(mxfd+1, &rd, &wr, to);
1186 while ((h = (TFileHandler *) next())) {
1187 Int_t fd = h->GetFd();
1206 Int_t TUnixSystem::Select(TFileHandler *h, Long_t to)
1216 if (h->HasReadInterest())
1218 if (h->HasWriteInterest())
1220 h->ResetReadyMask();
1222 rc = UnixSelect(mxfd+1, &rd, &wr, to);
1242 Bool_t TUnixSystem::CheckSignals(Bool_t sync)
1247 TOrdCollectionIter it((TOrdCollection*)fSignalHandler);
1249 while ((sh = (TSignalHandler*)it.Next())) {
1250 if (sync == sh->IsSync()) {
1251 ESignals sig = sh->GetSignal();
1252 if ((fSignals->IsSet(sig) && sigdone == -1) || sigdone == sig) {
1253 if (sigdone == -1) {
1273 void TUnixSystem::CheckChilds()
1277 while ((pid = UnixWaitchild()) > 0) {
1278 TIter next(zombieHandler);
1279 register UnixPtty *pty;
1280 while ((pty = (UnixPtty*) next()))
1281 if (pty->GetPid() == pid) {
1282 zombieHandler->RemovePtr(pty);
1293 Bool_t TUnixSystem::CheckDescriptors()
1297 Bool_t read = kFALSE;
1298 TOrdCollectionIter it((TOrdCollection*)fFileHandler);
1299 while ((fh = (TFileHandler*) it.Next())) {
1300 Int_t fd = fh->GetFd();
1301 if ((fd <= fMaxrfd && fReadready->IsSet(fd) && fddone == -1) ||
1302 (fddone == fd && read)) {
1304 fReadready->Clr(fd);
1312 if ((fd <= fMaxwfd && fWriteready->IsSet(fd) && fddone == -1) ||
1313 (fddone == fd && !read)) {
1315 fWriteready->Clr(fd);
1336 int TUnixSystem::MakeDirectory(
const char *name)
1338 TSystem *helper = FindHelper(name);
1340 return helper->MakeDirectory(name);
1342 return UnixMakedir(name);
1348 void *TUnixSystem::OpenDirectory(
const char *name)
1350 TSystem *helper = FindHelper(name);
1352 return helper->OpenDirectory(name);
1354 return UnixOpendir(name);
1360 void TUnixSystem::FreeDirectory(
void *dirp)
1362 TSystem *helper = FindHelper(0, dirp);
1364 helper->FreeDirectory(dirp);
1369 ::closedir((DIR*)dirp);
1375 const char *TUnixSystem::GetDirEntry(
void *dirp)
1377 TSystem *helper = FindHelper(0, dirp);
1379 return helper->GetDirEntry(dirp);
1382 return UnixGetdirentry(dirp);
1390 Bool_t TUnixSystem::ChangeDirectory(
const char *path)
1392 Bool_t ret = (Bool_t) (::chdir(path) == 0);
1401 const char *TUnixSystem::WorkingDirectory()
1407 R__LOCKGUARD2(gSystemMutex);
1409 static char cwd[kMAXPATHLEN];
1413 return fWdpath.Data();
1419 std::string TUnixSystem::GetWorkingDirectory()
const
1421 char cwd[kMAXPATHLEN];
1423 return std::string(cwd);
1429 void TUnixSystem::FillWithCwd(
char *cwd)
const
1431 if (::getcwd(cwd, kMAXPATHLEN) == 0) {
1432 Error(
"WorkingDirectory",
"getcwd() failed");
1439 const char *TUnixSystem::HomeDirectory(
const char *userName)
1441 return UnixHomedirectory(userName);
1447 std::string TUnixSystem::GetHomeDirectory(
const char *userName)
const
1449 char path[kMAXPATHLEN], mydir[kMAXPATHLEN] = {
'\0' };
1450 auto res = UnixHomedirectory(userName, path, mydir);
1451 if (res)
return std::string(res);
1452 else return std::string();
1459 const char *TUnixSystem::TempDirectory()
const
1461 const char *dir = gSystem->Getenv(
"TMPDIR");
1462 if (!dir || gSystem->AccessPathName(dir, kWritePermission))
1477 FILE *TUnixSystem::TempFileName(TString &base,
const char *dir)
1479 char *b = ConcatFileName(dir ? dir : TempDirectory(), base);
1484 char *arg = StrDup(base);
1485 int fd = mkstemp(arg);
1490 SysError(
"TempFileName",
"%s", base.Data());
1493 FILE *fp = fdopen(fd,
"w+");
1495 SysError(
"TempFileName",
"converting filedescriptor (%d)", fd);
1503 const char *TUnixSystem::PrependPathName(
const char *dir, TString& name)
1505 if (name.IsNull() || name ==
".") {
1508 if (dir[strlen(dir) - 1] !=
'/')
1514 if (!dir || !dir[0]) dir =
"/";
1515 else if (dir[strlen(dir) - 1] !=
'/')
1529 Bool_t TUnixSystem::AccessPathName(
const char *path, EAccessMode mode)
1531 TSystem *helper = FindHelper(path);
1533 return helper->AccessPathName(path, mode);
1535 if (::access(StripOffProto(path,
"file:"), mode) == 0)
1537 GetLastErrorString() = GetError();
1548 int TUnixSystem::CopyFile(
const char *f,
const char *t, Bool_t overwrite)
1550 if (!AccessPathName(t) && !overwrite)
1553 FILE *from = fopen(f,
"r");
1557 FILE *to = fopen(t,
"w");
1563 const int bufsize = 1024;
1566 while (!ret && !feof(from)) {
1567 size_t numread = fread (buf,
sizeof(
char), bufsize, from);
1568 size_t numwritten = fwrite(buf,
sizeof(
char), numread, to);
1569 if (numread != numwritten)
1582 int TUnixSystem::Rename(
const char *f,
const char *t)
1584 int ret = ::rename(f, t);
1585 GetLastErrorString() = GetError();
1593 Bool_t TUnixSystem::IsPathLocal(
const char *path)
1595 TSystem *helper = FindHelper(path);
1597 return helper->IsPathLocal(path);
1599 return TSystem::IsPathLocal(path);
1608 int TUnixSystem::GetPathInfo(
const char *path, FileStat_t &buf)
1610 TSystem *helper = FindHelper(path);
1612 return helper->GetPathInfo(path, buf);
1614 return UnixFilestat(path, buf);
1626 int TUnixSystem::GetFsInfo(
const char *path, Long_t *
id, Long_t *bsize,
1627 Long_t *blocks, Long_t *bfree)
1629 return UnixFSstat(path,
id, bsize, blocks, bfree);
1636 int TUnixSystem::Link(
const char *from,
const char *to)
1638 return ::link(from, to);
1645 int TUnixSystem::Symlink(
const char *from,
const char *to)
1648 return ::symlink((
char*)from, (
char*)to);
1650 return ::symlink(from, to);
1658 int TUnixSystem::Unlink(
const char *name)
1660 TSystem *helper = FindHelper(name);
1662 return helper->Unlink(name);
1664 #if defined(R__SEEK64)
1665 struct stat64 finfo;
1666 if (lstat64(name, &finfo) < 0)
1669 if (lstat(name, &finfo) < 0)
1673 if (S_ISDIR(finfo.st_mode))
1674 return ::rmdir(name);
1676 return ::unlink(name);
1685 kShellEscape =
'\\',
1686 *kShellStuff =
"(){}<>\"'",
1688 *kShellMeta =
"~*[]{}?$";
1691 #ifndef G__OLDEXPAND
1699 Bool_t TUnixSystem::ExpandPathName(TString &path)
1701 const char *p, *patbuf = (
const char *)path;
1704 while (*patbuf ==
' ')
1708 for (p = patbuf; *p; p++)
1709 if (strchr(kShellMeta, *p))
1716 path.ReplaceAll(
"$(",
"$");
1717 path.ReplaceAll(
")",
"");
1719 return ExpandFileName(path);
1731 Bool_t TUnixSystem::ExpandPathName(TString &patbuf0)
1733 const char *patbuf = (
const char *)patbuf0;
1736 char stuffedPat[kMAXPATHLEN], name[70];
1742 while (*patbuf ==
' ')
1746 for (p = patbuf; *p; p++)
1747 if (strchr(kShellMeta, *p))
1754 patbuf0.ReplaceAll(
"$(",
"$");
1755 patbuf0.ReplaceAll(
")",
"");
1758 EscChar(patbuf, stuffedPat,
sizeof(stuffedPat), (
char*)kShellStuff, kShellEscape);
1760 TString cmd(
"echo ");
1763 if (stuffedPat[0] ==
'~') {
1764 if (stuffedPat[1] !=
'\0' && stuffedPat[1] !=
'/') {
1766 for (p = &stuffedPat[1], q = name; *p && *p !=
'/';)
1769 hd = UnixHomedirectory(name);
1777 hd = UnixHomedirectory(0);
1779 GetLastErrorString() = GetError();
1783 cmd += &stuffedPat[1];
1788 if ((pf = ::popen(cmd.Data(),
"r")) == 0) {
1789 GetLastErrorString() = GetError();
1799 for (ch = fgetc(pf); ch != EOF && ch !=
' ' && ch !=
'\n'; ch = fgetc(pf)) {
1805 if (cnt == 0 && ch == EOF)
goto again;
1811 if (ch ==
' ' || ch ==
'\t') {
1812 GetLastErrorString() =
"expression ambigous";
1832 char *TUnixSystem::ExpandPathName(
const char *path)
1834 TString patbuf = path;
1835 if (ExpandPathName(patbuf))
1837 return StrDup(patbuf.Data());
1843 int TUnixSystem::Chmod(
const char *file, UInt_t mode)
1845 return ::chmod(file, mode);
1851 int TUnixSystem::Umask(Int_t mask)
1853 return ::umask(mask);
1860 int TUnixSystem::Utime(
const char *file, Long_t modtime, Long_t actime)
1866 t.actime = (time_t)actime;
1867 t.modtime = (time_t)modtime;
1868 return ::utime(file, &t);
1877 const char *TUnixSystem::FindFile(
const char *search, TString& wfil, EAccessMode mode)
1880 if (gEnv->GetValue(
"Root.ShowPath", 0))
1881 show.Form(
"Which: %s =", wfil.Data());
1883 gSystem->ExpandPathName(wfil);
1885 if (wfil[0] ==
'/') {
1886 #if defined(R__SEEK64)
1887 struct stat64 finfo;
1888 if (access(wfil.Data(), mode) == 0 &&
1889 stat64(wfil.Data(), &finfo) == 0 && S_ISREG(finfo.st_mode)) {
1892 if (access(wfil.Data(), mode) == 0 &&
1893 stat(wfil.Data(), &finfo) == 0 && S_ISREG(finfo.st_mode)) {
1896 Printf(
"%s %s", show.Data(), wfil.Data());
1900 Printf(
"%s <not found>", show.Data());
1908 TString apwd(gSystem->WorkingDirectory());
1910 for (
const char* ptr = search; *ptr;) {
1912 if (*ptr !=
'/' && *ptr !=
'$' && *ptr !=
'~')
1914 const char* posEndOfPart = strchr(ptr,
':');
1916 name.Append(ptr, posEndOfPart - ptr);
1917 ptr = posEndOfPart + 1;
1923 if (!name.EndsWith(
"/"))
1927 gSystem->ExpandPathName(name);
1928 #if defined(R__SEEK64)
1929 struct stat64 finfo;
1930 if (access(name.Data(), mode) == 0 &&
1931 stat64(name.Data(), &finfo) == 0 && S_ISREG(finfo.st_mode)) {
1934 if (access(name.Data(), mode) == 0 &&
1935 stat(name.Data(), &finfo) == 0 && S_ISREG(finfo.st_mode)) {
1938 Printf(
"%s %s", show.Data(), name.Data());
1945 Printf(
"%s <not found>", show.Data());
1955 Int_t TUnixSystem::GetUid(
const char *user)
1957 if (!user || !user[0])
1960 struct passwd *apwd = getpwnam(user);
1962 return apwd->pw_uid;
1971 Int_t TUnixSystem::GetEffectiveUid()
1979 Int_t TUnixSystem::GetGid(
const char *group)
1981 if (!group || !group[0])
1984 struct group *grp = getgrnam(group);
1995 Int_t TUnixSystem::GetEffectiveGid()
2004 UserGroup_t *TUnixSystem::GetUserInfo(Int_t uid)
2006 typedef std::map<Int_t , UserGroup_t> UserInfoCache_t;
2007 static UserInfoCache_t gUserInfo;
2009 UserInfoCache_t::const_iterator iUserInfo = gUserInfo.find(uid);
2010 if (iUserInfo != gUserInfo.end())
2011 return new UserGroup_t(iUserInfo->second);
2013 struct passwd *apwd = getpwuid(uid);
2015 UserGroup_t *ug =
new UserGroup_t;
2016 ug->fUid = apwd->pw_uid;
2017 ug->fGid = apwd->pw_gid;
2018 ug->fUser = apwd->pw_name;
2019 ug->fPasswd = apwd->pw_passwd;
2020 ug->fRealName = apwd->pw_gecos;
2021 ug->fShell = apwd->pw_shell;
2022 UserGroup_t *gr = GetGroupInfo(apwd->pw_gid);
2023 if (gr) ug->fGroup = gr->fGroup;
2026 gUserInfo[uid] = *ug;
2037 UserGroup_t *TUnixSystem::GetUserInfo(
const char *user)
2039 return GetUserInfo(GetUid(user));
2049 UserGroup_t *TUnixSystem::GetGroupInfo(Int_t gid)
2051 struct group *grp = getgrgid(gid);
2053 UserGroup_t *gr =
new UserGroup_t;
2055 gr->fGid = grp->gr_gid;
2056 gr->fGroup = grp->gr_name;
2069 UserGroup_t *TUnixSystem::GetGroupInfo(
const char *group)
2071 return GetGroupInfo(GetGid(group));
2079 void TUnixSystem::Setenv(
const char *name,
const char *value)
2081 ::setenv(name, value, 1);
2087 const char *TUnixSystem::Getenv(
const char *name)
2089 return ::getenv(name);
2095 void TUnixSystem::Unsetenv(
const char *name)
2105 int TUnixSystem::Exec(
const char *shellcmd)
2107 return ::system(shellcmd);
2113 FILE *TUnixSystem::OpenPipe(
const char *command,
const char *mode)
2115 return ::popen(command, mode);
2121 int TUnixSystem::ClosePipe(FILE *pipe)
2123 return ::pclose(pipe);
2129 int TUnixSystem::GetPid()
2137 void TUnixSystem::Exit(
int code, Bool_t mode)
2152 void TUnixSystem::Abort(
int)
2160 #include <mach/mach.h>
2168 typedef CSTypeRef CSSymbolicatorRef;
2169 typedef CSTypeRef CSSourceInfoRef;
2170 typedef CSTypeRef CSSymbolOwnerRef;
2171 typedef CSTypeRef CSSymbolRef;
2173 CSSymbolicatorRef CSSymbolicatorCreateWithPid(pid_t pid);
2174 CSSymbolRef CSSymbolicatorGetSymbolWithAddressAtTime(CSSymbolicatorRef cs, vm_address_t addr, uint64_t time);
2175 CSSourceInfoRef CSSymbolicatorGetSourceInfoWithAddressAtTime(CSSymbolicatorRef cs, vm_address_t addr, uint64_t time);
2176 const char* CSSymbolGetName(CSSymbolRef sym);
2177 CSSymbolOwnerRef CSSymbolGetSymbolOwner(CSSymbolRef sym);
2178 const char* CSSymbolOwnerGetPath(CSSymbolOwnerRef symbol);
2179 const char* CSSourceInfoGetPath(CSSourceInfoRef info);
2180 int CSSourceInfoGetLineNumber(CSSourceInfoRef info);
2183 bool CSTypeRefIdValid(CSTypeRef ref) {
2184 return ref.csCppData || ref.csCppObj;
2187 void macosx_backtrace() {
2188 void* addrlist[kMAX_BACKTRACE_DEPTH];
2190 int numstacks = backtrace( addrlist,
sizeof( addrlist ) /
sizeof(
void* ));
2192 CSSymbolicatorRef symbolicator = CSSymbolicatorCreateWithPid(getpid());
2195 static const int skipFrames = 2;
2196 for (
int i = skipFrames; i < numstacks; ++i) {
2198 CSSymbolRef sym = CSSymbolicatorGetSymbolWithAddressAtTime(symbolicator,
2199 (vm_address_t)addrlist[i],
2201 CSSymbolOwnerRef symOwner = CSSymbolGetSymbolOwner(sym);
2203 if (
const char* libPath = CSSymbolOwnerGetPath(symOwner)) {
2204 printf(
"[%s]", libPath);
2206 printf(
"[<unknown binary>]");
2209 if (
const char* symname = CSSymbolGetName(sym)) {
2210 printf(
" %s", symname);
2213 CSSourceInfoRef sourceInfo
2214 = CSSymbolicatorGetSourceInfoWithAddressAtTime(symbolicator,
2215 (vm_address_t)addrlist[i],
2217 if (
const char* sourcePath = CSSourceInfoGetPath(sourceInfo)) {
2218 printf(
" %s:%d", sourcePath, (
int)CSSourceInfoGetLineNumber(sourceInfo));
2220 printf(
" (no debug info)");
2230 void TUnixSystem::StackTrace()
2232 if (!gEnv->GetValue(
"Root.Stacktrace", 1))
2236 TString gdbscript = gEnv->GetValue(
"Root.StacktraceScript",
"");
2237 gdbscript = gdbscript.Strip();
2238 if (gdbscript !=
"") {
2239 if (AccessPathName(gdbscript, kReadPermission)) {
2240 fprintf(stderr,
"Root.StacktraceScript %s does not exist\n", gdbscript.Data());
2244 if (gdbscript ==
"") {
2245 gdbscript =
"gdb-backtrace.sh";
2246 gSystem->PrependPathName(TROOT::GetEtcDir(), gdbscript);
2247 if (AccessPathName(gdbscript, kReadPermission)) {
2248 fprintf(stderr,
"Error in <TUnixSystem::StackTrace> script %s is missing\n", gdbscript.Data());
2254 TString gdbmess = gEnv->GetValue(
"Root.StacktraceMessage",
"");
2255 gdbmess = gdbmess.Strip();
2263 int fd = STDERR_FILENO;
2265 const char *message =
" Generating stack trace...\n";
2267 if (fd && message) { }
2269 if (gApplication && !strcmp(gApplication->GetName(),
"TRint"))
2270 Getlinem(kCleanUp, 0);
2272 #if defined(USE_GDB_STACK_TRACE)
2273 char *gdb = Which(Getenv(
"PATH"),
"gdb", kExecutePermission);
2275 fprintf(stderr,
"gdb not found, need it for stack trace\n");
2280 TString gdbmessf =
"gdb-message";
2281 if (gdbmess !=
"") {
2282 FILE *f = TempFileName(gdbmessf);
2283 fprintf(f,
"%s\n", gdbmess.Data());
2288 gdbscript += GetExePath();
2290 gdbscript += GetPid();
2291 if (gdbmess !=
"") {
2293 gdbscript += gdbmessf;
2295 gdbscript +=
" 1>&2";
2300 #elif defined(R__AIX)
2301 TString script =
"procstack ";
2305 #elif defined(R__SOLARIS)
2306 char *cppfilt = Which(Getenv(
"PATH"),
"c++filt", kExecutePermission);
2307 TString script =
"pstack ";
2316 #elif defined(HAVE_BACKTRACE_SYMBOLS_FD) && defined(HAVE_DLADDR) // linux + MacOS X >= 10.5
2321 Bool_t demangle = kTRUE;
2324 const char *cppfilt =
"c++filt";
2325 const char *cppfiltarg =
"";
2327 const char *format1 =
" 0x%016lx in %.200s %s 0x%lx from %.200s\n";
2329 const char *format2 =
" 0x%016lx in %.200s\n";
2331 const char *format2 =
" 0x%016lx in %.200s at %.200s from %.200s\n";
2333 const char *format3 =
" 0x%016lx in %.200s from %.200s\n";
2334 const char *format4 =
" 0x%016lx in <unknown function>\n";
2336 const char *format1 =
" 0x%08lx in %.200s %s 0x%lx from %.200s\n";
2338 const char *format2 =
" 0x%08lx in %.200s\n";
2340 const char *format2 =
" 0x%08lx in %.200s at %.200s from %.200s\n";
2342 const char *format3 =
" 0x%08lx in %.200s from %.200s\n";
2343 const char *format4 =
" 0x%08lx in <unknown function>\n";
2346 char *filter = Which(Getenv(
"PATH"), cppfilt, kExecutePermission);
2353 FILE *p = OpenPipe(TString::Format(
"%s --help 2>&1", filter),
"r");
2355 while (help.Gets(p)) {
2356 if (help.Index(
"gnu-v3") != kNPOS) {
2357 cppfiltarg =
"--format=gnu-v3";
2359 }
else if (help.Index(
"gnu-new-abi") != kNPOS) {
2360 cppfiltarg =
"--format=gnu-new-abi";
2369 #if (defined(R__LINUX) && !defined(R__WINGCC))
2372 #ifdef PR_SET_PTRACER
2373 prctl(PR_SET_PTRACER, getpid(), 0, 0, 0);
2376 char *gdb = Which(Getenv(
"PATH"),
"gdb", kExecutePermission);
2379 TString gdbmessf =
"gdb-message";
2380 if (gdbmess !=
"") {
2381 FILE *f = TempFileName(gdbmessf);
2382 fprintf(f,
"%s\n", gdbmess.Data());
2388 gdbscript += GetExePath();
2391 gdbscript += GetPid();
2392 if (gdbmess !=
"") {
2394 gdbscript += gdbmessf;
2396 gdbscript +=
" 1>&2";
2403 char *addr2line = Which(Getenv(
"PATH"),
"atos", kExecutePermission);
2405 char *addr2line = Which(Getenv(
"PATH"),
"addr2line", kExecutePermission);
2409 if (write(fd, message, strlen(message)) < 0)
2410 Warning(
"StackTrace",
"problems writing line numbers (errno: %d)", TSystem::GetErrno());
2414 TString tmpf1 =
"gdb-backtrace";
2415 std::ofstream file1;
2417 FILE *f = TempFileName(tmpf1);
2421 Error(
"StackTrace",
"could not open file %s", tmpf1.Data());
2433 void *trace[kMAX_BACKTRACE_DEPTH];
2434 int depth = backtrace(trace, kMAX_BACKTRACE_DEPTH);
2435 for (
int n = 5; n < depth; n++) {
2436 ULong_t addr = (ULong_t) trace[n];
2439 if (dladdr(trace[n], &info) && info.dli_fname && info.dli_fname[0]) {
2440 const char *libname = info.dli_fname;
2441 const char *symname = (info.dli_sname && info.dli_sname[0]) ?
2442 info.dli_sname :
"<unknown>";
2443 ULong_t libaddr = (ULong_t) info.dli_fbase;
2444 ULong_t symaddr = (ULong_t) info.dli_saddr;
2445 Bool_t gte = (addr >= symaddr);
2446 ULong_t diff = (gte) ? addr - symaddr : symaddr - addr;
2447 if (addr2line && symaddr) {
2448 Bool_t nodebug = kTRUE;
2451 #if defined(MAC_OS_X_VERSION_10_10)
2452 snprintf(buffer,
sizeof(buffer),
"%s -p %d 0x%016lx", addr2line, GetPid(), addr);
2453 #elif defined(MAC_OS_X_VERSION_10_9)
2455 snprintf(buffer,
sizeof(buffer),
"%s -d -p %d 0x%016lx", addr2line, GetPid(), addr);
2457 snprintf(buffer,
sizeof(buffer),
"%s -p %d 0x%016lx", addr2line, GetPid(), addr);
2460 ULong_t offset = (addr >= libaddr) ? addr - libaddr :
2462 TString name = TString(libname);
2463 Bool_t noPath = kFALSE;
2464 Bool_t noShare = kTRUE;
2465 if (name[0] !=
'/') noPath = kTRUE;
2466 if (name.Contains(
".so") || name.Contains(
".sl")) noShare = kFALSE;
2467 if (noShare) offset = addr;
2468 if (noPath) name =
"`which " + name +
"`";
2469 snprintf(buffer,
sizeof(buffer),
"%s -e %s 0x%016lx", addr2line, name.Data(), offset);
2471 if (FILE *pf = ::popen(buffer,
"r")) {
2473 if (fgets(buf, 2048, pf)) {
2474 buf[strlen(buf)-1] = 0;
2475 if (strncmp(buf,
"??", 2)) {
2477 snprintf(buffer,
sizeof(buffer), format2, addr, buf);
2479 snprintf(buffer,
sizeof(buffer), format2, addr, symname, buf, libname);
2487 snprintf(buffer,
sizeof(buffer), format1, addr, symname,
2488 gte ?
"+" :
"-", diff, libname);
2491 snprintf(buffer,
sizeof(buffer), format1, addr, symname,
2492 gte ?
"+" :
"-", diff, libname);
2494 snprintf(buffer,
sizeof(buffer), format3, addr, symname, libname);
2497 snprintf(buffer,
sizeof(buffer), format4, addr);
2503 if (write(fd, buffer, ::strlen(buffer)) < 0)
2504 Warning(
"StackTrace",
"problems writing buffer (errno: %d)", TSystem::GetErrno());
2508 TString tmpf2 =
"gdb-backtrace";
2509 FILE *f = TempFileName(tmpf2);
2512 snprintf(buffer,
sizeof(buffer),
"%s %s < %s > %s", filter, cppfiltarg, tmpf1.Data(), tmpf2.Data());
2514 std::ifstream file2(tmpf2);
2518 line.ReadString(file2);
2519 if (write(fd, line.Data(), line.Length()) < 0)
2520 Warning(
"StackTrace",
"problems writing line (errno: %d)", TSystem::GetErrno());
2527 delete [] addr2line;
2530 #elif defined(HAVE_EXCPT_H) && defined(HAVE_PDSC_H) && \
2531 defined(HAVE_RLD_INTERFACE_H) // tru64
2540 exc_capture_context (&context);
2541 while (!rc && context.sc_pc) {
2543 pdsc_crd *func, *base, *crd
2544 = exc_remote_lookup_function_entry(0, 0, context.sc_pc, 0, &func, &base);
2545 Elf32_Addr addr = PDSC_CRD_BEGIN_ADDRESS(base, func);
2547 const char *name =
"<unknown function>";
2548 sprintf(buffer,
" 0x%012lx %.200s + 0x%lx\n",
2549 context.sc_pc, name, context.sc_pc - addr);
2550 write(fd, buffer, ::strlen(buffer));
2551 rc = exc_virtual_unwind(0, &context);
2565 void TUnixSystem::Openlog(
const char *name, Int_t options, ELogFacility facility)
2596 ::openlog(name, options, fac);
2603 void TUnixSystem::Syslog(ELogLevel level,
const char *mess)
2606 ::syslog(level,
"%s", mess);
2612 void TUnixSystem::Closelog()
2631 Int_t TUnixSystem::RedirectOutput(
const char *file,
const char *mode,
2632 RedirectHandle_t *h)
2635 static RedirectHandle_t loch;
2640 RedirectHandle_t *xh = (h) ? h : &loch;
2644 Bool_t outdone = kFALSE;
2645 if (xh->fStdOutTty.IsNull()) {
2646 const char *tty = ttyname(STDOUT_FILENO);
2648 xh->fStdOutTty = tty;
2650 if ((xh->fStdOutDup = dup(STDOUT_FILENO)) < 0) {
2651 SysError(
"RedirectOutput",
"could not 'dup' stdout (errno: %d)", TSystem::GetErrno());
2657 if (xh->fStdErrTty.IsNull()) {
2658 const char *tty = ttyname(STDERR_FILENO);
2660 xh->fStdErrTty = tty;
2662 if ((xh->fStdErrDup = dup(STDERR_FILENO)) < 0) {
2663 SysError(
"RedirectOutput",
"could not 'dup' stderr (errno: %d)", TSystem::GetErrno());
2664 if (outdone && dup2(xh->fStdOutDup, STDOUT_FILENO) < 0) {
2665 Warning(
"RedirectOutput",
"could not restore stdout (back to original redirected"
2666 " file) (errno: %d)", TSystem::GetErrno());
2674 const char *m = (mode[0] ==
'a' || mode[0] ==
'w') ? mode :
"a";
2677 xh->fReadOffSet = 0;
2681 if (!gSystem->GetPathInfo(file, st))
2682 xh->fReadOffSet = (st.fSize > 0) ? st.fSize : xh->fReadOffSet;
2687 if (freopen(file, m, stdout) == 0) {
2688 SysError(
"RedirectOutput",
"could not freopen stdout (errno: %d)", TSystem::GetErrno());
2691 if (freopen(file, m, stderr) == 0) {
2692 SysError(
"RedirectOutput",
"could not freopen stderr (errno: %d)", TSystem::GetErrno());
2693 if (freopen(xh->fStdOutTty.Data(),
"a", stdout) == 0)
2694 SysError(
"RedirectOutput",
"could not restore stdout (errno: %d)", TSystem::GetErrno());
2700 if (!(xh->fStdOutTty.IsNull())) {
2701 if (freopen(xh->fStdOutTty.Data(),
"a", stdout) == 0) {
2702 SysError(
"RedirectOutput",
"could not restore stdout (errno: %d)", TSystem::GetErrno());
2705 xh->fStdOutTty =
"";
2707 if (close(STDOUT_FILENO) != 0) {
2708 SysError(
"RedirectOutput",
2709 "problems closing STDOUT_FILENO (%d) before 'dup2' (errno: %d)",
2710 STDOUT_FILENO, TSystem::GetErrno());
2713 if (dup2(xh->fStdOutDup, STDOUT_FILENO) < 0) {
2714 SysError(
"RedirectOutput",
"could not restore stdout (back to original redirected"
2715 " file) (errno: %d)", TSystem::GetErrno());
2718 if (close(xh->fStdOutDup) != 0) {
2719 SysError(
"RedirectOutput",
2720 "problems closing temporary 'out' descriptor %d (errno: %d)",
2721 TSystem::GetErrno(), xh->fStdOutDup);
2726 if (!(xh->fStdErrTty.IsNull())) {
2727 if (freopen(xh->fStdErrTty.Data(),
"a", stderr) == 0) {
2728 SysError(
"RedirectOutput",
"could not restore stderr (errno: %d)", TSystem::GetErrno());
2731 xh->fStdErrTty =
"";
2733 if (close(STDERR_FILENO) != 0) {
2734 SysError(
"RedirectOutput",
2735 "problems closing STDERR_FILENO (%d) before 'dup2' (errno: %d)",
2736 STDERR_FILENO, TSystem::GetErrno());
2739 if (dup2(xh->fStdErrDup, STDERR_FILENO) < 0) {
2740 SysError(
"RedirectOutput",
"could not restore stderr (back to original redirected"
2741 " file) (errno: %d)", TSystem::GetErrno());
2744 if (close(xh->fStdErrDup) != 0) {
2745 SysError(
"RedirectOutput",
2746 "problems closing temporary 'err' descriptor %d (errno: %d)",
2747 TSystem::GetErrno(), xh->fStdErrDup);
2763 Func_t TUnixSystem::DynFindSymbol(
const char * ,
const char *entry)
2765 return TSystem::DynFindSymbol(
"*", entry);
2773 int TUnixSystem::Load(
const char *module,
const char *entry, Bool_t system)
2775 return TSystem::Load(module, entry, system);
2781 void TUnixSystem::Unload(
const char *module)
2783 if (module) { TSystem::Unload(module); }
2789 void TUnixSystem::ListSymbols(
const char * ,
const char * )
2791 Error(
"ListSymbols",
"not yet implemented");
2797 void TUnixSystem::ListLibraries(
const char *regexp)
2799 TSystem::ListLibraries(regexp);
2806 const char *TUnixSystem::GetLinkedLibraries()
2808 static TString linkedLibs;
2809 static Bool_t once = kFALSE;
2811 R__LOCKGUARD2(gSystemMutex);
2813 if (!linkedLibs.IsNull())
2819 #if !defined(R__MACOSX)
2820 const char *exe = GetExePath();
2825 #if defined(R__MACOSX)
2827 linkedLibs = gLinkedDylibs;
2829 FILE *p = OpenPipe(TString::Format(
"otool -L %s", exe),
"r");
2831 while (otool.Gets(p)) {
2832 TString delim(
" \t");
2833 TObjArray *tok = otool.Tokenize(delim);
2834 TString dylib = ((TObjString*)tok->At(0))->String();
2835 if (dylib.EndsWith(
".dylib") && !dylib.Contains(
"/libSystem.B.dylib")) {
2836 if (!linkedLibs.IsNull())
2838 linkedLibs += dylib;
2846 #elif defined(R__LINUX) || defined(R__SOLARIS) || defined(R__AIX)
2847 #if defined(R__WINGCC )
2848 const char *cLDD=
"cygcheck";
2849 const char *cSOEXT=
".dll";
2850 size_t lenexe = strlen(exe);
2851 if (strcmp(exe + lenexe - 4,
".exe")
2852 && strcmp(exe + lenexe - 4,
".dll")) {
2855 char* longerexe =
new char[lenexe + 5];
2856 strlcpy(longerexe, exe,lenexe+5);
2857 strlcat(longerexe,
".exe",lenexe+5);
2861 TRegexp sovers =
"\\.so\\.[0-9]+";
2863 const char *cLDD=
"ldd";
2865 const char *cSOEXT=
".a";
2866 TRegexp sovers =
"\\.a\\.[0-9]+";
2868 const char *cSOEXT=
".so";
2869 TRegexp sovers =
"\\.so\\.[0-9]+";
2872 FILE *p = OpenPipe(TString::Format(
"%s '%s'", cLDD, exe),
"r");
2875 while (ldd.Gets(p)) {
2876 TString delim(
" \t");
2877 TObjArray *tok = ldd.Tokenize(delim);
2881 TObjString *solibName = (TObjString*)tok->At(2);
2885 solibName = (TObjString*)tok->At(0);
2888 TString solib = solibName->String();
2889 Ssiz_t idx = solib.Index(sovers);
2890 if (solib.EndsWith(cSOEXT) || idx != kNPOS) {
2892 solib.Remove(idx+3);
2893 if (!AccessPathName(solib, kReadPermission)) {
2894 if (!linkedLibs.IsNull())
2896 linkedLibs += solib;
2908 if (linkedLibs.IsNull())
2919 TTime TUnixSystem::Now()
2928 Bool_t TUnixSystem::DispatchTimers(Bool_t mode)
2930 if (!fTimers)
return kFALSE;
2932 fInsideNotify = kTRUE;
2934 TOrdCollectionIter it((TOrdCollection*)fTimers);
2936 Bool_t timedout = kFALSE;
2938 while ((t = (TTimer *) it.Next())) {
2940 Long64_t now = UnixNow();
2941 if (mode && t->IsSync()) {
2942 if (t->CheckTimer(now))
2944 }
else if (!mode && t->IsAsync()) {
2945 if (t->CheckTimer(now)) {
2946 UnixSetitimer(NextTimeOut(kFALSE));
2951 fInsideNotify = kFALSE;
2958 void TUnixSystem::AddTimer(TTimer *ti)
2960 TSystem::AddTimer(ti);
2967 TTimer *TUnixSystem::RemoveTimer(TTimer *ti)
2971 R__LOCKGUARD2(gSystemMutex);
2973 TTimer *t = TSystem::RemoveTimer(ti);
2975 UnixSetitimer(NextTimeOut(kFALSE));
2982 void TUnixSystem::ResetTimer(TTimer *ti)
2984 if (!fInsideNotify && ti && ti->IsAsync())
2985 UnixSetitimer(NextTimeOut(kFALSE));
2995 TInetAddress TUnixSystem::GetHostByName(
const char *hostname)
2998 struct addrinfo hints;
2999 struct addrinfo *result, *rp;
3000 memset(&hints, 0,
sizeof(
struct addrinfo));
3001 hints.ai_family = AF_INET;
3002 hints.ai_socktype = 0;
3003 hints.ai_protocol = 0;
3004 hints.ai_flags = AI_CANONNAME;
3009 size_t lenHostname = strlen(hostname);
3010 std::string hostnameWithoutLocal{hostname};
3011 if (lenHostname > 6 && !strcmp(hostname + lenHostname - 6,
".local")) {
3012 hostnameWithoutLocal.erase(lenHostname - 6);
3013 hostname = hostnameWithoutLocal.c_str();
3018 int rc = getaddrinfo(hostname,
nullptr, &hints, &result);
3020 if (rc == EAI_NONAME) {
3021 if (gDebug > 0) Error(
"GetHostByName",
"unknown host '%s'", hostname);
3022 ia.fHostname =
"UnNamedHost";
3024 Error(
"GetHostByName",
"getaddrinfo failed for '%s': %s", hostname, gai_strerror(rc));
3025 ia.fHostname =
"UnknownHost";
3030 std::string hostcanon(result->ai_canonname ? result->ai_canonname : hostname);
3031 ia.fHostname = hostcanon.data();
3032 ia.fFamily = result->ai_family;
3033 ia.fAddresses[0] = ntohl(((
struct sockaddr_in *)(result->ai_addr))->sin_addr.s_addr);
3035 if (hostcanon.compare(hostname) != 0) ia.AddAlias(hostname);
3038 char tmp[
sizeof(
struct in_addr)];
3039 if (inet_pton(AF_INET, hostcanon.data(), tmp) == 1) {
3040 char hbuf[NI_MAXHOST];
3041 if (getnameinfo(result->ai_addr, result->ai_addrlen, hbuf,
sizeof(hbuf),
nullptr, 0, 0) == 0)
3042 ia.fHostname = hbuf;
3046 rp = result->ai_next;
3047 for (; rp !=
nullptr; rp = rp->ai_next) {
3048 UInt_t arp = ntohl(((
struct sockaddr_in *)(rp->ai_addr))->sin_addr.s_addr);
3049 if ( !(std::find(ia.fAddresses.begin(), ia.fAddresses.end(), arp) != ia.fAddresses.end()) )
3053 freeaddrinfo(result);
3060 TInetAddress TUnixSystem::GetSockName(
int sock)
3062 struct sockaddr addr;
3063 #if defined(USE_SIZE_T)
3064 size_t len =
sizeof(addr);
3065 #elif defined(USE_SOCKLEN_T)
3066 socklen_t len =
sizeof(addr);
3068 int len =
sizeof(addr);
3072 if (getsockname(sock, &addr, &len) == -1) {
3073 SysError(
"GetSockName",
"getsockname failed");
3077 if (addr.sa_family != AF_INET)
return ia;
3078 ia.fFamily = addr.sa_family;
3079 struct sockaddr_in *addrin = (
struct sockaddr_in *)&addr;
3080 ia.fPort = ntohs(addrin->sin_port);
3081 ia.fAddresses[0] = ntohl(addrin->sin_addr.s_addr);
3083 char hbuf[NI_MAXHOST];
3084 if (getnameinfo(&addr,
sizeof(
struct sockaddr), hbuf,
sizeof(hbuf),
nullptr, 0, 0) != 0) {
3085 Error(
"GetSockName",
"getnameinfo failed");
3086 ia.fHostname =
"????";
3088 ia.fHostname = hbuf;
3096 TInetAddress TUnixSystem::GetPeerName(
int sock)
3098 struct sockaddr addr;
3099 #if defined(USE_SIZE_T)
3100 size_t len =
sizeof(addr);
3101 #elif defined(USE_SOCKLEN_T)
3102 socklen_t len =
sizeof(addr);
3104 int len =
sizeof(addr);
3108 if (getpeername(sock, &addr, &len) == -1) {
3109 SysError(
"GetPeerName",
"getpeername failed");
3113 if (addr.sa_family != AF_INET)
return ia;
3114 ia.fFamily = addr.sa_family;
3115 struct sockaddr_in *addrin = (
struct sockaddr_in *)&addr;
3116 ia.fPort = ntohs(addrin->sin_port);
3117 ia.fAddresses[0] = ntohl(addrin->sin_addr.s_addr);
3119 char hbuf[NI_MAXHOST];
3120 if (getnameinfo(&addr,
sizeof(
struct sockaddr), hbuf,
sizeof(hbuf),
nullptr, 0, 0) != 0) {
3121 Error(
"GetPeerName",
"getnameinfo failed");
3122 ia.fHostname =
"????";
3124 ia.fHostname = hbuf;
3132 int TUnixSystem::GetServiceByName(
const char *servicename)
3136 if ((sp = getservbyname(servicename, kProtocolName)) == 0) {
3137 Error(
"GetServiceByName",
"no service \"%s\" with protocol \"%s\"\n",
3138 servicename, kProtocolName);
3141 return ntohs(sp->s_port);
3147 char *TUnixSystem::GetServiceByPort(
int port)
3151 if ((sp = getservbyport(htons(port), kProtocolName)) == 0) {
3154 return Form(
"%d", port);
3162 int TUnixSystem::ConnectService(
const char *servername,
int port,
3163 int tcpwindowsize,
const char *protocol)
3165 if (!strcmp(servername,
"unix")) {
3166 return UnixUnixConnect(port);
3167 }
else if (!gSystem->AccessPathName(servername) || servername[0] ==
'/') {
3168 return UnixUnixConnect(servername);
3171 if (!strcmp(protocol,
"udp")){
3172 return UnixUdpConnect(servername, port);
3175 return UnixTcpConnect(servername, port, tcpwindowsize);
3186 int TUnixSystem::OpenConnection(
const char *server,
int port,
int tcpwindowsize,
const char *protocol)
3188 return ConnectService(server, port, tcpwindowsize, protocol);
3202 int TUnixSystem::AnnounceTcpService(
int port, Bool_t reuse,
int backlog,
3205 return UnixTcpService(port, reuse, backlog, tcpwindowsize);
3211 int TUnixSystem::AnnounceUdpService(
int port,
int backlog)
3213 return UnixUdpService(port, backlog);
3219 int TUnixSystem::AnnounceUnixService(
int port,
int backlog)
3221 return UnixUnixService(port, backlog);
3227 int TUnixSystem::AnnounceUnixService(
const char *sockpath,
int backlog)
3229 return UnixUnixService(sockpath, backlog);
3237 int TUnixSystem::AcceptConnection(
int sock)
3241 while ((soc = ::accept(sock, 0, 0)) == -1 && GetErrno() == EINTR)
3245 if (GetErrno() == EWOULDBLOCK)
3248 SysError(
"AcceptConnection",
"accept");
3259 void TUnixSystem::CloseConnection(
int sock, Bool_t force)
3261 if (sock < 0)
return;
3263 #if !defined(R__AIX) || defined(_AIX41) || defined(_AIX43)
3265 ::shutdown(sock, 2);
3268 while (::close(sock) == -1 && GetErrno() == EINTR)
3277 int TUnixSystem::RecvBuf(
int sock,
void *buf,
int length)
3281 if (UnixRecv(sock, &header,
sizeof(header), 0) > 0) {
3282 int count = ntohl(header);
3284 if (count > length) {
3285 Error(
"RecvBuf",
"record header exceeds buffer size");
3287 }
else if (count > 0) {
3288 if (UnixRecv(sock, buf, count, 0) < 0) {
3289 Error(
"RecvBuf",
"cannot receive buffer");
3302 int TUnixSystem::SendBuf(
int sock,
const void *buf,
int length)
3304 Int_t header = htonl(length);
3306 if (UnixSend(sock, &header,
sizeof(header), 0) < 0) {
3307 Error(
"SendBuf",
"cannot send header");
3311 if (UnixSend(sock, buf, length, 0) < 0) {
3312 Error(
"SendBuf",
"cannot send buffer");
3329 int TUnixSystem::RecvRaw(
int sock,
void *buf,
int length,
int opt)
3352 if ((n = UnixRecv(sock, buf, length, flag)) <= 0) {
3353 if (n == -1 && GetErrno() != EINTR)
3354 Error(
"RecvRaw",
"cannot receive buffer");
3366 int TUnixSystem::SendRaw(
int sock,
const void *buf,
int length,
int opt)
3387 if ((n = UnixSend(sock, buf, length, flag)) <= 0) {
3388 if (n == -1 && GetErrno() != EINTR)
3389 Error(
"SendRaw",
"cannot send buffer");
3398 int TUnixSystem::SetSockOpt(
int sock,
int opt,
int val)
3400 if (sock < 0)
return -1;
3404 if (setsockopt(sock, SOL_SOCKET, SO_SNDBUF, (
char*)&val,
sizeof(val)) == -1) {
3405 SysError(
"SetSockOpt",
"setsockopt(SO_SNDBUF)");
3410 if (setsockopt(sock, SOL_SOCKET, SO_RCVBUF, (
char*)&val,
sizeof(val)) == -1) {
3411 SysError(
"SetSockOpt",
"setsockopt(SO_RCVBUF)");
3416 if (setsockopt(sock, SOL_SOCKET, SO_OOBINLINE, (
char*)&val,
sizeof(val)) == -1) {
3417 SysError(
"SetSockOpt",
"setsockopt(SO_OOBINLINE)");
3422 if (setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, (
char*)&val,
sizeof(val)) == -1) {
3423 SysError(
"SetSockOpt",
"setsockopt(SO_KEEPALIVE)");
3428 if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (
char*)&val,
sizeof(val)) == -1) {
3429 SysError(
"SetSockOpt",
"setsockopt(SO_REUSEADDR)");
3434 if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (
char*)&val,
sizeof(val)) == -1) {
3435 SysError(
"SetSockOpt",
"setsockopt(TCP_NODELAY)");
3440 if (ioctl(sock, FIONBIO, (
char*)&val) == -1) {
3441 SysError(
"SetSockOpt",
"ioctl(FIONBIO)");
3447 if (ioctl(sock, SIOCSPGRP, (
char*)&val) == -1) {
3448 SysError(
"SetSockOpt",
"ioctl(SIOCSPGRP)");
3452 Error(
"SetSockOpt",
"ioctl(SIOCGPGRP) not supported on cygwin/gcc");
3459 Error(
"SetSockOpt",
"illegal option (%d)", opt);
3468 int TUnixSystem::GetSockOpt(
int sock,
int opt,
int *val)
3470 if (sock < 0)
return -1;
3472 #if defined(USE_SOCKLEN_T) || defined(_AIX43)
3473 socklen_t optlen =
sizeof(*val);
3474 #elif defined(USE_SIZE_T)
3475 size_t optlen =
sizeof(*val);
3477 int optlen =
sizeof(*val);
3482 if (getsockopt(sock, SOL_SOCKET, SO_SNDBUF, (
char*)val, &optlen) == -1) {
3483 SysError(
"GetSockOpt",
"getsockopt(SO_SNDBUF)");
3488 if (getsockopt(sock, SOL_SOCKET, SO_RCVBUF, (
char*)val, &optlen) == -1) {
3489 SysError(
"GetSockOpt",
"getsockopt(SO_RCVBUF)");
3494 if (getsockopt(sock, SOL_SOCKET, SO_OOBINLINE, (
char*)val, &optlen) == -1) {
3495 SysError(
"GetSockOpt",
"getsockopt(SO_OOBINLINE)");
3500 if (getsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, (
char*)val, &optlen) == -1) {
3501 SysError(
"GetSockOpt",
"getsockopt(SO_KEEPALIVE)");
3506 if (getsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (
char*)val, &optlen) == -1) {
3507 SysError(
"GetSockOpt",
"getsockopt(SO_REUSEADDR)");
3512 if (getsockopt(sock, IPPROTO_TCP, TCP_NODELAY, (
char*)val, &optlen) == -1) {
3513 SysError(
"GetSockOpt",
"getsockopt(TCP_NODELAY)");
3519 if ((flg = fcntl(sock, F_GETFL, 0)) == -1) {
3520 SysError(
"GetSockOpt",
"fcntl(F_GETFL)");
3523 *val = flg & O_NDELAY;
3526 #if !defined(R__LYNXOS) && !defined(R__WINGCC)
3527 if (ioctl(sock, SIOCGPGRP, (
char*)val) == -1) {
3528 SysError(
"GetSockOpt",
"ioctl(SIOCGPGRP)");
3532 Error(
"GetSockOpt",
"ioctl(SIOCGPGRP) not supported on LynxOS and cygwin/gcc");
3537 #if !defined(R__LYNXOS)
3538 if (ioctl(sock, SIOCATMARK, (
char*)val) == -1) {
3539 SysError(
"GetSockOpt",
"ioctl(SIOCATMARK)");
3543 Error(
"GetSockOpt",
"ioctl(SIOCATMARK) not supported on LynxOS");
3548 #if !defined(R__LYNXOS)
3549 if (ioctl(sock, FIONREAD, (
char*)val) == -1) {
3550 SysError(
"GetSockOpt",
"ioctl(FIONREAD)");
3554 Error(
"GetSockOpt",
"ioctl(FIONREAD) not supported on LynxOS");
3559 Error(
"GetSockOpt",
"illegal option (%d)", opt);
3574 static struct Signalmap_t {
3576 SigHandler_t fHandler;
3577 struct sigaction *fOldHandler;
3578 const char *fSigName;
3579 } gSignalMap[kMAXSIGNALS] = {
3580 { SIGBUS, 0, 0,
"bus error" },
3581 { SIGSEGV, 0, 0,
"segmentation violation" },
3582 { SIGSYS, 0, 0,
"bad argument to system call" },
3583 { SIGPIPE, 0, 0,
"write on a pipe with no one to read it" },
3584 { SIGILL, 0, 0,
"illegal instruction" },
3585 { SIGQUIT, 0, 0,
"quit" },
3586 { SIGINT, 0, 0,
"interrupt" },
3587 { SIGWINCH, 0, 0,
"window size change" },
3588 { SIGALRM, 0, 0,
"alarm clock" },
3589 { SIGCHLD, 0, 0,
"death of a child" },
3590 { SIGURG, 0, 0,
"urgent data arrived on an I/O channel" },
3591 { SIGFPE, 0, 0,
"floating point exception" },
3592 { SIGTERM, 0, 0,
"termination signal" },
3593 { SIGUSR1, 0, 0,
"user-defined signal 1" },
3594 { SIGUSR2, 0, 0,
"user-defined signal 2" }
3601 static void sighandler(
int sig)
3603 for (
int i= 0; i < kMAXSIGNALS; i++) {
3604 if (gSignalMap[i].fCode == sig) {
3605 (*gSignalMap[i].fHandler)((ESignals)i);
3614 void TUnixSystem::DispatchSignals(ESignals sig)
3618 DispatchTimers(kFALSE);
3624 case kSigSegmentationViolation:
3625 case kSigIllegalInstruction:
3626 case kSigFloatingException:
3627 Break(
"TUnixSystem::DispatchSignals",
"%s", UnixSigname(sig));
3631 gApplication->HandleException(sig);
3635 Exit(gSignalMap[sig].fCode + 0x80);
3639 Break(
"TUnixSystem::DispatchSignals",
"%s", UnixSigname(sig));
3641 case kSigWindowChanged:
3645 Break(
"TUnixSystem::DispatchSignals",
"%s: printing stacktrace", UnixSigname(sig));
3655 if (fSigcnt > 0 && fSignalHandler->GetSize() > 0)
3656 CheckSignals(kFALSE);
3662 void TUnixSystem::UnixSignal(ESignals sig, SigHandler_t handler)
3664 if (gEnv && !gEnv->GetValue(
"Root.ErrorHandlers", 1))
3667 if (gSignalMap[sig].fHandler != handler) {
3668 struct sigaction sigact;
3670 gSignalMap[sig].fHandler = handler;
3671 gSignalMap[sig].fOldHandler =
new struct sigaction();
3674 sigact.sa_handler = (void (*)())sighandler;
3675 #elif defined(R__SOLARIS)
3676 sigact.sa_handler = sighandler;
3677 #elif defined(R__LYNXOS)
3679 sigact.sa_handler = sighandler;
3681 sigact.sa_handler = (void (*)(...))sighandler;
3684 sigact.sa_handler = sighandler;
3686 sigemptyset(&sigact.sa_mask);
3687 sigact.sa_flags = 0;
3688 #if defined(SA_RESTART)
3689 sigact.sa_flags |= SA_RESTART;
3691 if (sigaction(gSignalMap[sig].fCode, &sigact,
3692 gSignalMap[sig].fOldHandler) < 0)
3693 ::SysError(
"TUnixSystem::UnixSignal",
"sigaction");
3701 void TUnixSystem::UnixIgnoreSignal(ESignals sig, Bool_t ignore)
3703 TTHREAD_TLS(Bool_t) ignoreSig[kMAXSIGNALS] = { kFALSE };
3704 TTHREAD_TLS_ARRAY(
struct sigaction,kMAXSIGNALS,oldsigact);
3706 if (ignore != ignoreSig[sig]) {
3707 ignoreSig[sig] = ignore;
3709 struct sigaction sigact;
3711 sigact.sa_handler = (void (*)())SIG_IGN;
3712 #elif defined(R__SOLARIS)
3713 sigact.sa_handler = (void (*)(int))SIG_IGN;
3715 sigact.sa_handler = SIG_IGN;
3717 sigemptyset(&sigact.sa_mask);
3718 sigact.sa_flags = 0;
3719 if (sigaction(gSignalMap[sig].fCode, &sigact, &oldsigact[sig]) < 0)
3720 ::SysError(
"TUnixSystem::UnixIgnoreSignal",
"sigaction");
3722 if (sigaction(gSignalMap[sig].fCode, &oldsigact[sig], 0) < 0)
3723 ::SysError(
"TUnixSystem::UnixIgnoreSignal",
"sigaction");
3736 void TUnixSystem::UnixSigAlarmInterruptsSyscalls(Bool_t set)
3738 if (gSignalMap[kSigAlarm].fHandler) {
3739 struct sigaction sigact;
3741 sigact.sa_handler = (void (*)())sighandler;
3742 #elif defined(R__SOLARIS)
3743 sigact.sa_handler = sighandler;
3744 #elif defined(R__LYNXOS)
3746 sigact.sa_handler = sighandler;
3748 sigact.sa_handler = (void (*)(...))sighandler;
3751 sigact.sa_handler = sighandler;
3753 sigemptyset(&sigact.sa_mask);
3754 sigact.sa_flags = 0;
3756 #if defined(SA_INTERRUPT) // SunOS
3757 sigact.sa_flags |= SA_INTERRUPT;
3760 #if defined(SA_RESTART)
3761 sigact.sa_flags |= SA_RESTART;
3764 if (sigaction(gSignalMap[kSigAlarm].fCode, &sigact, 0) < 0)
3765 ::SysError(
"TUnixSystem::UnixSigAlarmInterruptsSyscalls",
"sigaction");
3772 const char *TUnixSystem::UnixSigname(ESignals sig)
3774 return gSignalMap[sig].fSigName;
3780 void TUnixSystem::UnixResetSignal(ESignals sig)
3782 if (gSignalMap[sig].fOldHandler) {
3784 if (sigaction(gSignalMap[sig].fCode, gSignalMap[sig].fOldHandler, 0) < 0)
3785 ::SysError(
"TUnixSystem::UnixSignal",
"sigaction");
3786 delete gSignalMap[sig].fOldHandler;
3787 gSignalMap[sig].fOldHandler = 0;
3788 gSignalMap[sig].fHandler = 0;
3795 void TUnixSystem::UnixResetSignals()
3797 for (
int sig = 0; sig < kMAXSIGNALS; sig++)
3798 UnixResetSignal((ESignals)sig);
3806 Long64_t TUnixSystem::UnixNow()
3808 static std::atomic<time_t> jan95{0};
3819 jan95 = mktime(&tp);
3820 if ((
int)jan95 == -1) {
3821 ::SysError(
"TUnixSystem::UnixNow",
"error converting 950001 0:00 to time_t");
3827 gettimeofday(&t, 0);
3828 return Long64_t(t.tv_sec-(Long_t)jan95)*1000 + t.tv_usec/1000;
3834 int TUnixSystem::UnixSetitimer(Long_t ms)
3836 struct itimerval itv;
3837 itv.it_value.tv_sec = 0;
3838 itv.it_value.tv_usec = 0;
3839 itv.it_interval.tv_sec = 0;
3840 itv.it_interval.tv_usec = 0;
3842 itv.it_value.tv_sec = time_t(ms / 1000);
3843 itv.it_value.tv_usec = time_t((ms % 1000) * 1000);
3845 int st = setitimer(ITIMER_REAL, &itv, 0);
3847 ::SysError(
"TUnixSystem::UnixSetitimer",
"setitimer");
3860 int TUnixSystem::UnixSelect(Int_t nfds, TFdSet *readready, TFdSet *writeready,
3865 fd_set *rd = (readready) ? (fd_set*)readready->GetBits() : 0;
3866 fd_set *wr = (writeready) ? (fd_set*)writeready->GetBits() : 0;
3870 tv.tv_sec = Int_t(timeout / 1000);
3871 tv.tv_usec = (timeout % 1000) * 1000;
3872 retcode = select(nfds, rd, wr, 0, &tv);
3874 retcode = select(nfds, rd, wr, 0, 0);
3876 if (retcode == -1) {
3877 if (GetErrno() == EINTR) {
3881 if (GetErrno() == EBADF)
3894 const char *TUnixSystem::UnixHomedirectory(
const char *name)
3896 static char path[kMAXPATHLEN], mydir[kMAXPATHLEN] = {
'\0' };
3897 return UnixHomedirectory(name, path, mydir);
3903 const char *TUnixSystem::UnixHomedirectory(
const char *name,
char *path,
char *mydir)
3907 pw = getpwnam(name);
3909 strncpy(path, pw->pw_dir, kMAXPATHLEN-1);
3910 path[kMAXPATHLEN-1] =
'\0';
3916 pw = getpwuid(getuid());
3917 if (pw && pw->pw_dir) {
3918 strncpy(mydir, pw->pw_dir, kMAXPATHLEN-1);
3919 mydir[kMAXPATHLEN-1] =
'\0';
3921 }
else if (gSystem->Getenv(
"HOME")) {
3922 strncpy(mydir, gSystem->Getenv(
"HOME"), kMAXPATHLEN-1);
3923 mydir[kMAXPATHLEN-1] =
'\0';
3935 int TUnixSystem::UnixMakedir(
const char *dir)
3937 return ::mkdir(StripOffProto(dir,
"file:"), 0755);
3943 void *TUnixSystem::UnixOpendir(
const char *dir)
3947 const char *edir = StripOffProto(dir,
"file:");
3949 if (stat(edir, &finfo) < 0)
3952 if (!S_ISDIR(finfo.st_mode))
3955 return (
void*) opendir(edir);
3958 #if defined(_POSIX_SOURCE)
3961 # define REAL_DIR_ENTRY(dp) 1
3963 # define REAL_DIR_ENTRY(dp) (dp->d_ino != 0)
3969 const char *TUnixSystem::UnixGetdirentry(
void *dirp1)
3971 DIR *dirp = (DIR*)dirp1;
3983 if (REAL_DIR_ENTRY(dp))
3998 int TUnixSystem::UnixFilestat(
const char *fpath, FileStat_t &buf)
4000 const char *path = StripOffProto(fpath,
"file:");
4001 buf.fIsLink = kFALSE;
4003 #if defined(R__SEEK64)
4005 if (path && lstat64(path, &sbuf) == 0) {
4008 if (path && lstat(path, &sbuf) == 0) {
4010 buf.fIsLink = S_ISLNK(sbuf.st_mode);
4012 #if defined(R__SEEK64)
4013 if (stat64(path, &sbuf) == -1) {
4015 if (stat(path, &sbuf) == -1) {
4020 buf.fDev = sbuf.st_dev;
4021 buf.fIno = sbuf.st_ino;
4022 buf.fMode = sbuf.st_mode;
4023 buf.fUid = sbuf.st_uid;
4024 buf.fGid = sbuf.st_gid;
4025 buf.fSize = sbuf.st_size;
4026 buf.fMtime = sbuf.st_mtime;
4042 int TUnixSystem::UnixFSstat(
const char *path, Long_t *
id, Long_t *bsize,
4043 Long_t *blocks, Long_t *bfree)
4045 struct statfs statfsbuf;
4046 #if (defined(R__SOLARIS) && !defined(R__LINUX))
4047 if (statfs(path, &statfsbuf,
sizeof(
struct statfs), 0) == 0) {
4048 *
id = statfsbuf.f_fstyp;
4049 *bsize = statfsbuf.f_bsize;
4050 *blocks = statfsbuf.f_blocks;
4051 *bfree = statfsbuf.f_bfree;
4053 if (statfs((
char*)path, &statfsbuf) == 0) {
4059 if (!strcmp(statfsbuf.f_fstypename, MOUNT_FFS) ||
4060 !strcmp(statfsbuf.f_fstypename, MOUNT_MFS))
4062 else if (!strcmp(statfsbuf.f_fstypename, MOUNT_NFS))
4064 else if (!strcmp(statfsbuf.f_fstypename, MOUNT_MSDOS))
4066 else if (!strcmp(statfsbuf.f_fstypename, MOUNT_EXT2FS))
4068 else if (!strcmp(statfsbuf.f_fstypename, MOUNT_CD9660))
4070 else if (!strcmp(statfsbuf.f_fstypename, MOUNT_NCPFS))
4075 *
id = statfsbuf.f_type;
4077 *bsize = statfsbuf.f_bsize;
4078 *blocks = statfsbuf.f_blocks;
4079 *bfree = statfsbuf.f_bavail;
4089 int TUnixSystem::UnixWaitchild()
4092 return (
int) waitpid(0, &status, WNOHANG);
4104 int TUnixSystem::UnixTcpConnect(
const char *hostname,
int port,
4110 if ((sp = getservbyport(htons(port), kProtocolName)))
4113 sport = htons(port);
4115 TInetAddress addr = gSystem->GetHostByName(hostname);
4116 if (!addr.IsValid())
return -1;
4117 UInt_t adr = htonl(addr.GetAddress());
4119 struct sockaddr_in server;
4120 memset(&server, 0,
sizeof(server));
4121 memcpy(&server.sin_addr, &adr,
sizeof(adr));
4122 server.sin_family = addr.GetFamily();
4123 server.sin_port = sport;
4127 if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
4128 ::SysError(
"TUnixSystem::UnixTcpConnect",
"socket (%s:%d)",
4133 if (tcpwindowsize > 0) {
4134 gSystem->SetSockOpt(sock, kRecvBuffer, tcpwindowsize);
4135 gSystem->SetSockOpt(sock, kSendBuffer, tcpwindowsize);
4138 while (connect(sock, (
struct sockaddr*) &server,
sizeof(server)) == -1) {
4139 if (GetErrno() == EINTR)
4142 ::SysError(
"TUnixSystem::UnixTcpConnect",
"connect (%s:%d)",
4156 int TUnixSystem::UnixUdpConnect(
const char *hostname,
int port)
4161 if ((sp = getservbyport(htons(port), kProtocolName)))
4164 sport = htons(port);
4166 TInetAddress addr = gSystem->GetHostByName(hostname);
4167 if (!addr.IsValid())
return -1;
4168 UInt_t adr = htonl(addr.GetAddress());
4170 struct sockaddr_in server;
4171 memset(&server, 0,
sizeof(server));
4172 memcpy(&server.sin_addr, &adr,
sizeof(adr));
4173 server.sin_family = addr.GetFamily();
4174 server.sin_port = sport;
4178 if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
4179 ::SysError(
"TUnixSystem::UnixUdpConnect",
"socket (%s:%d)",
4184 while (connect(sock, (
struct sockaddr*) &server,
sizeof(server)) == -1) {
4185 if (GetErrno() == EINTR)
4188 ::SysError(
"TUnixSystem::UnixUdpConnect",
"connect (%s:%d)",
4200 int TUnixSystem::UnixUnixConnect(
int port)
4202 return UnixUnixConnect(TString::Format(
"%s/%d", kServerPath, port));
4208 int TUnixSystem::UnixUnixConnect(
const char *sockpath)
4210 if (!sockpath || strlen(sockpath) <= 0) {
4211 ::SysError(
"TUnixSystem::UnixUnixConnect",
"socket path undefined");
4216 struct sockaddr_un unserver;
4217 unserver.sun_family = AF_UNIX;
4219 if (strlen(sockpath) >
sizeof(unserver.sun_path)-1) {
4220 ::Error(
"TUnixSystem::UnixUnixConnect",
"socket path %s, longer than max allowed length (%u)",
4221 sockpath, (UInt_t)
sizeof(unserver.sun_path)-1);
4224 strcpy(unserver.sun_path, sockpath);
4227 if ((sock = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
4228 ::SysError(
"TUnixSystem::UnixUnixConnect",
"socket");
4232 while (connect(sock, (
struct sockaddr*) &unserver, strlen(unserver.sun_path)+2) == -1) {
4233 if (GetErrno() == EINTR)
4236 ::SysError(
"TUnixSystem::UnixUnixConnect",
"connect");
4256 int TUnixSystem::UnixTcpService(
int port, Bool_t reuse,
int backlog,
4259 const short kSOCKET_MINPORT = 5000, kSOCKET_MAXPORT = 15000;
4260 short sport, tryport = kSOCKET_MINPORT;
4263 if (port == 0 && reuse) {
4264 ::Error(
"TUnixSystem::UnixTcpService",
"cannot do a port scan while reuse is true");
4268 if ((sp = getservbyport(htons(port), kProtocolName)))
4271 sport = htons(port);
4275 if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
4276 ::SysError(
"TUnixSystem::UnixTcpService",
"socket");
4281 gSystem->SetSockOpt(sock, kReuseAddr, 1);
4283 if (tcpwindowsize > 0) {
4284 gSystem->SetSockOpt(sock, kRecvBuffer, tcpwindowsize);
4285 gSystem->SetSockOpt(sock, kSendBuffer, tcpwindowsize);
4288 struct sockaddr_in inserver;
4289 memset(&inserver, 0,
sizeof(inserver));
4290 inserver.sin_family = AF_INET;
4291 inserver.sin_addr.s_addr = htonl(INADDR_ANY);
4292 inserver.sin_port = sport;
4296 if (::bind(sock, (
struct sockaddr*) &inserver,
sizeof(inserver))) {
4297 ::SysError(
"TUnixSystem::UnixTcpService",
"bind");
4304 inserver.sin_port = htons(tryport);
4305 bret = ::bind(sock, (
struct sockaddr*) &inserver,
sizeof(inserver));
4307 }
while (bret < 0 && GetErrno() == EADDRINUSE && tryport < kSOCKET_MAXPORT);
4309 ::SysError(
"TUnixSystem::UnixTcpService",
"bind (port scan)");
4316 if (::listen(sock, backlog)) {
4317 ::SysError(
"TUnixSystem::UnixTcpService",
"listen");
4332 int TUnixSystem::UnixUdpService(
int port,
int backlog)
4334 const short kSOCKET_MINPORT = 5000, kSOCKET_MAXPORT = 15000;
4335 short sport, tryport = kSOCKET_MINPORT;
4338 if ((sp = getservbyport(htons(port), kProtocolName)))
4341 sport = htons(port);
4345 if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
4346 ::SysError(
"TUnixSystem::UnixUdpService",
"socket");
4350 struct sockaddr_in inserver;
4351 memset(&inserver, 0,
sizeof(inserver));
4352 inserver.sin_family = AF_INET;
4353 inserver.sin_addr.s_addr = htonl(INADDR_ANY);
4354 inserver.sin_port = sport;
4358 if (::bind(sock, (
struct sockaddr*) &inserver,
sizeof(inserver))) {
4359 ::SysError(
"TUnixSystem::UnixUdpService",
"bind");
4366 inserver.sin_port = htons(tryport);
4367 bret = ::bind(sock, (
struct sockaddr*) &inserver,
sizeof(inserver));
4369 }
while (bret < 0 && GetErrno() == EADDRINUSE && tryport < kSOCKET_MAXPORT);
4371 ::SysError(
"TUnixSystem::UnixUdpService",
"bind (port scan)");
4378 if (::listen(sock, backlog)) {
4379 ::SysError(
"TUnixSystem::UnixUdpService",
"listen");
4391 int TUnixSystem::UnixUnixService(
int port,
int backlog)
4396 oldumask = umask(0);
4397 int res = ::mkdir(kServerPath, 0777);
4405 sockpath.Form(
"%s/%d", kServerPath, port);
4408 unlink(sockpath.Data());
4410 return UnixUnixService(sockpath, backlog);
4417 int TUnixSystem::UnixUnixService(
const char *sockpath,
int backlog)
4419 if (!sockpath || strlen(sockpath) <= 0) {
4420 ::SysError(
"TUnixSystem::UnixUnixService",
"socket path undefined");
4424 struct sockaddr_un unserver;
4428 memset(&unserver, 0,
sizeof(unserver));
4429 unserver.sun_family = AF_UNIX;
4431 if (strlen(sockpath) >
sizeof(unserver.sun_path)-1) {
4432 ::Error(
"TUnixSystem::UnixUnixService",
"socket path %s, longer than max allowed length (%u)",
4433 sockpath, (UInt_t)
sizeof(unserver.sun_path)-1);
4436 strcpy(unserver.sun_path, sockpath);
4439 if ((sock = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
4440 ::SysError(
"TUnixSystem::UnixUnixService",
"socket");
4444 if (::bind(sock, (
struct sockaddr*) &unserver, strlen(unserver.sun_path)+2)) {
4445 ::SysError(
"TUnixSystem::UnixUnixService",
"bind");
4451 if (::listen(sock, backlog)) {
4452 ::SysError(
"TUnixSystem::UnixUnixService",
"listen");
4467 int TUnixSystem::UnixRecv(
int sock,
void *buffer,
int length,
int flag)
4471 if (sock < 0)
return -1;
4478 if (flag == MSG_PEEK)
4482 char *buf = (
char *)buffer;
4484 for (n = 0; n < length; n += nrecv) {
4485 if ((nrecv = recv(sock, buf+n, length-n, flag)) <= 0) {
4488 if (flag == MSG_OOB) {
4489 if (GetErrno() == EWOULDBLOCK)
4491 else if (GetErrno() == EINVAL)
4494 if (GetErrno() == EWOULDBLOCK)
4497 if (GetErrno() != EINTR)
4498 ::SysError(
"TUnixSystem::UnixRecv",
"recv");
4499 if (GetErrno() == EPIPE || GetErrno() == ECONNRESET)
4517 int TUnixSystem::UnixSend(
int sock,
const void *buffer,
int length,
int flag)
4519 if (sock < 0)
return -1;
4528 const char *buf = (
const char *)buffer;
4530 for (n = 0; n < length; n += nsent) {
4531 if ((nsent = send(sock, buf+n, length-n, flag)) <= 0) {
4534 if (GetErrno() == EWOULDBLOCK)
4537 if (GetErrno() != EINTR)
4538 ::SysError(
"TUnixSystem::UnixSend",
"send");
4539 if (GetErrno() == EPIPE || GetErrno() == ECONNRESET)
4556 static const char *DynamicPath(
const char *newpath = 0, Bool_t reset = kFALSE)
4558 static TString dynpath;
4559 static Bool_t initialized = kFALSE;
4569 }
else if (reset || !initialized) {
4570 initialized = kTRUE;
4571 TString rdynpath = gEnv->GetValue(
"Root.DynamicPath", (
char*)0);
4572 rdynpath.ReplaceAll(
": ",
":");
4573 if (rdynpath.IsNull()) {
4574 rdynpath =
".:"; rdynpath += TROOT::GetLibDir();
4577 #if defined (R__AIX)
4578 ldpath = gSystem->Getenv(
"LIBPATH");
4579 #elif defined(R__MACOSX)
4580 ldpath = gSystem->Getenv(
"DYLD_LIBRARY_PATH");
4581 if (!ldpath.IsNull())
4583 ldpath += gSystem->Getenv(
"LD_LIBRARY_PATH");
4584 if (!ldpath.IsNull())
4586 ldpath += gSystem->Getenv(
"DYLD_FALLBACK_LIBRARY_PATH");
4588 ldpath = gSystem->Getenv(
"LD_LIBRARY_PATH");
4590 if (ldpath.IsNull())
4593 dynpath = ldpath; dynpath +=
":"; dynpath += rdynpath;
4595 if (!dynpath.Contains(TROOT::GetLibDir())) {
4596 dynpath +=
":"; dynpath += TROOT::GetLibDir();
4599 dynpath +=
":"; dynpath += gCling->GetSTLIncludePath();
4601 initialized = kFALSE;
4603 #if defined(R__WINGCC) || defined(R__MACOSX)
4604 if (!dynpath.EndsWith(
":")) dynpath +=
":";
4605 dynpath +=
"/usr/local/lib:/usr/X11R6/lib:/usr/lib:/lib:";
4606 dynpath +=
"/lib/x86_64-linux-gnu:/usr/local/lib64:/usr/lib64:/lib64:";
4609 std::string cmd(
"LD_DEBUG=libs LD_PRELOAD=DOESNOTEXIST ls 2>&1");
4610 FILE *pf = popen(cmd.c_str (),
"r");
4611 std::string result =
"";
4614 if (fgets(buffer, 128, pf) != NULL)
4618 std::size_t from = result.find(
"search path=", result.find(
"(LD_LIBRARY_PATH)"));
4619 std::size_t to = result.find(
"(system search path)");
4620 if (from != std::string::npos && to != std::string::npos) {
4622 std::string sys_path = result.substr(from, to-from);
4623 sys_path.erase(std::remove_if(sys_path.begin(), sys_path.end(), isspace), sys_path.end());
4624 if (!dynpath.EndsWith(
":")) dynpath +=
":";
4625 dynpath += sys_path.c_str();
4627 dynpath.ReplaceAll(
"::",
":");
4629 if (gDebug > 0) std::cout <<
"dynpath = " << dynpath.Data() << std::endl;
4637 void TUnixSystem::AddDynamicPath(
const char *path)
4640 TString oldpath = DynamicPath(0, kFALSE);
4641 oldpath.Append(
":");
4642 oldpath.Append(path);
4643 DynamicPath(oldpath);
4650 const char *TUnixSystem::GetDynamicPath()
4652 return DynamicPath(0, kFALSE);
4660 void TUnixSystem::SetDynamicPath(
const char *path)
4663 DynamicPath(0, kTRUE);
4673 const char *TUnixSystem::FindDynamicLibrary(TString& sLib, Bool_t quiet)
4675 char buf[PATH_MAX + 1];
4676 char *res = realpath(sLib.Data(), buf);
4677 if (res) sLib = buf;
4678 TString searchFor = sLib;
4679 if (gSystem->FindFile(GetDynamicPath(), sLib, kReadPermission)) {
4683 const char* lib = sLib.Data();
4684 int len = sLib.Length();
4685 if (len > 3 && (!strcmp(lib+len-3,
".so") ||
4686 !strcmp(lib+len-3,
".dl") ||
4687 !strcmp(lib+len-4,
".dll") ||
4688 !strcmp(lib+len-4,
".DLL") ||
4689 !strcmp(lib+len-6,
".dylib") ||
4690 !strcmp(lib+len-3,
".sl") ||
4691 !strcmp(lib+len-2,
".a"))) {
4692 if (gSystem->FindFile(GetDynamicPath(), sLib, kReadPermission)) {
4696 Error(
"FindDynamicLibrary",
4697 "%s does not exist in %s", searchFor.Data(), GetDynamicPath());
4700 static const char* exts[] = {
4701 ".so",
".dll",
".dylib",
".sl",
".dl",
".a", 0 };
4702 const char** ext = exts;
4704 TString fname(sLib);
4707 if (gSystem->FindFile(GetDynamicPath(), fname, kReadPermission)) {
4714 Error(
"FindDynamicLibrary",
4715 "%s[.so | .dll | .dylib | .sl | .dl | .a] does not exist in %s",
4716 searchFor.Data(), GetDynamicPath());
4723 #if defined(R__MACOSX)
4724 #include <sys/resource.h>
4725 #include <mach/mach.h>
4726 #include <mach/mach_error.h>
4731 static void GetDarwinSysInfo(SysInfo_t *sysinfo)
4733 FILE *p = gSystem->OpenPipe(
"sysctl -n kern.ostype hw.model hw.ncpu hw.cpufrequency "
4734 "hw.busfrequency hw.l2cachesize hw.memsize",
"r");
4739 sysinfo->fModel = s;
4741 sysinfo->fCpus = s.Atoi();
4743 Long64_t t = s.Atoll();
4744 sysinfo->fCpuSpeed = Int_t(t / 1000000);
4747 sysinfo->fBusSpeed = Int_t(t / 1000000);
4749 sysinfo->fL2Cache = s.Atoi() / 1024;
4752 sysinfo->fPhysRam = Int_t(t / 1024 / 1024);
4753 gSystem->ClosePipe(p);
4754 p = gSystem->OpenPipe(
"hostinfo",
"r");
4756 if (s.BeginsWith(
"Processor type: ")) {
4757 TPRegexp(
"Processor type: ([^ ]+).*").Substitute(s,
"$1");
4758 sysinfo->fCpuType = s;
4761 gSystem->ClosePipe(p);
4767 static void ReadDarwinCpu(
long *ticks)
4769 mach_msg_type_number_t count;
4771 host_cpu_load_info_data_t cpu;
4773 ticks[0] = ticks[1] = ticks[2] = ticks[3] = 0;
4775 count = HOST_CPU_LOAD_INFO_COUNT;
4776 kr = host_statistics(mach_host_self(), HOST_CPU_LOAD_INFO, (host_info_t)&cpu, &count);
4777 if (kr != KERN_SUCCESS) {
4778 ::Error(
"TUnixSystem::ReadDarwinCpu",
"host_statistics: %s", mach_error_string(kr));
4780 ticks[0] = cpu.cpu_ticks[CPU_STATE_USER];
4781 ticks[1] = cpu.cpu_ticks[CPU_STATE_SYSTEM];
4782 ticks[2] = cpu.cpu_ticks[CPU_STATE_IDLE];
4783 ticks[3] = cpu.cpu_ticks[CPU_STATE_NICE];
4791 static void GetDarwinCpuInfo(CpuInfo_t *cpuinfo, Int_t sampleTime)
4794 if (getloadavg(avg,
sizeof(avg)) < 0) {
4795 ::Error(
"TUnixSystem::GetDarwinCpuInfo",
"getloadavg failed");
4797 cpuinfo->fLoad1m = (Float_t)avg[0];
4798 cpuinfo->fLoad5m = (Float_t)avg[1];
4799 cpuinfo->fLoad15m = (Float_t)avg[2];
4802 Long_t cpu_ticks1[4], cpu_ticks2[4];
4803 ReadDarwinCpu(cpu_ticks1);
4804 gSystem->Sleep(sampleTime);
4805 ReadDarwinCpu(cpu_ticks2);
4807 Long_t userticks = (cpu_ticks2[0] + cpu_ticks2[3]) -
4808 (cpu_ticks1[0] + cpu_ticks1[3]);
4809 Long_t systicks = cpu_ticks2[1] - cpu_ticks1[1];
4810 Long_t idleticks = cpu_ticks2[2] - cpu_ticks1[2];
4811 if (userticks < 0) userticks = 0;
4812 if (systicks < 0) systicks = 0;
4813 if (idleticks < 0) idleticks = 0;
4814 Long_t totalticks = userticks + systicks + idleticks;
4816 cpuinfo->fUser = ((Float_t)(100 * userticks)) / ((Float_t)totalticks);
4817 cpuinfo->fSys = ((Float_t)(100 * systicks)) / ((Float_t)totalticks);
4818 cpuinfo->fTotal = cpuinfo->fUser + cpuinfo->fSys;
4819 cpuinfo->fIdle = ((Float_t)(100 * idleticks)) / ((Float_t)totalticks);
4826 static void GetDarwinMemInfo(MemInfo_t *meminfo)
4828 static Int_t pshift = 0;
4830 vm_statistics_data_t vm_info;
4831 mach_msg_type_number_t count;
4834 Long64_t total, used, free, swap_total, swap_used;
4836 count = HOST_VM_INFO_COUNT;
4837 kr = host_statistics(mach_host_self(), HOST_VM_INFO, (host_info_t)&vm_info, &count);
4838 if (kr != KERN_SUCCESS) {
4839 ::Error(
"TUnixSystem::GetDarwinMemInfo",
"host_statistics: %s", mach_error_string(kr));
4843 for (
int psize = getpagesize(); psize > 1; psize >>= 1)
4847 used = (Long64_t)(vm_info.active_count + vm_info.inactive_count + vm_info.wire_count) << pshift;
4848 free = (Long64_t)(vm_info.free_count) << pshift;
4849 total = (Long64_t)(vm_info.active_count + vm_info.inactive_count + vm_info.free_count + vm_info.wire_count) << pshift;
4852 swap_used = vm_info.pageouts << pshift;
4855 dirp = opendir(
"/private/var/vm");
4860 while ((dp = readdir(dirp)) != 0) {
4862 char fname [MAXNAMLEN];
4863 if (strncmp(dp->d_name,
"swapfile", 8))
4865 strlcpy(fname,
"/private/var/vm/",MAXNAMLEN);
4866 strlcat (fname, dp->d_name,MAXNAMLEN);
4867 if (stat(fname, &sb) < 0)
4869 swap_total += sb.st_size;
4873 meminfo->fMemTotal = (Int_t) (total >> 20);
4874 meminfo->fMemUsed = (Int_t) (used >> 20);
4875 meminfo->fMemFree = (Int_t) (free >> 20);
4876 meminfo->fSwapTotal = (Int_t) (swap_total >> 20);
4877 meminfo->fSwapUsed = (Int_t) (swap_used >> 20);
4878 meminfo->fSwapFree = meminfo->fSwapTotal - meminfo->fSwapUsed;
4889 static void GetDarwinProcInfo(ProcInfo_t *procinfo)
4892 #define vm_region vm_region_64
4896 #define GLOBAL_SHARED_TEXT_SEGMENT 0x90000000U
4897 #define GLOBAL_SHARED_DATA_SEGMENT 0xA0000000U
4898 #define SHARED_TEXT_REGION_SIZE 0x10000000
4899 #define SHARED_DATA_REGION_SIZE 0x10000000
4902 if (getrusage(RUSAGE_SELF, &ru) < 0) {
4903 ::SysError(
"TUnixSystem::GetDarwinProcInfo",
"getrusage failed");
4905 procinfo->fCpuUser = (Float_t)(ru.ru_utime.tv_sec) +
4906 ((Float_t)(ru.ru_utime.tv_usec) / 1000000.);
4907 procinfo->fCpuSys = (Float_t)(ru.ru_stime.tv_sec) +
4908 ((Float_t)(ru.ru_stime.tv_usec) / 1000000.);
4911 task_basic_info_data_t ti;
4912 mach_msg_type_number_t count;
4915 task_t a_task = mach_task_self();
4917 count = TASK_BASIC_INFO_COUNT;
4918 kr = task_info(a_task, TASK_BASIC_INFO, (task_info_t)&ti, &count);
4919 if (kr != KERN_SUCCESS) {
4920 ::Error(
"TUnixSystem::GetDarwinProcInfo",
"task_info: %s", mach_error_string(kr));
4925 mach_port_t object_name;
4926 vm_address_t address;
4927 vm_region_top_info_data_t info;
4928 vm_size_t vsize, vprvt, rsize, size;
4929 rsize = ti.resident_size;
4930 vsize = ti.virtual_size;
4932 for (address = 0; ; address += size) {
4934 count = VM_REGION_TOP_INFO_COUNT;
4935 if (vm_region(a_task, &address, &size,
4936 VM_REGION_TOP_INFO, (vm_region_info_t)&info, &count,
4937 &object_name) != KERN_SUCCESS) {
4942 if (address >= GLOBAL_SHARED_TEXT_SEGMENT &&
4943 address < (GLOBAL_SHARED_DATA_SEGMENT + SHARED_DATA_REGION_SIZE)) {
4948 if (info.share_mode == SM_EMPTY) {
4949 vm_region_basic_info_data_64_t b_info;
4950 count = VM_REGION_BASIC_INFO_COUNT_64;
4951 if (vm_region_64(a_task, &address,
4952 &size, VM_REGION_BASIC_INFO,
4953 (vm_region_info_t)&b_info, &count,
4954 &object_name) != KERN_SUCCESS) {
4958 if (b_info.reserved) {
4959 vsize -= (SHARED_TEXT_REGION_SIZE + SHARED_DATA_REGION_SIZE);
4966 if (info.share_mode != SM_PRIVATE) {
4970 switch (info.share_mode) {
4972 if (info.ref_count == 1) {
4975 vprvt += info.private_pages_resident * getpagesize();
4988 procinfo->fMemResident = (Long_t)(rsize / 1024);
4990 procinfo->fMemVirtual = (Long_t)(vprvt / 1024);
4995 #if defined(R__LINUX)
4999 static void GetLinuxSysInfo(SysInfo_t *sysinfo)
5002 FILE *f = fopen(
"/proc/cpuinfo",
"r");
5005 if (s.BeginsWith(
"model name")) {
5006 TPRegexp(
"^.+: *(.*$)").Substitute(s,
"$1");
5007 sysinfo->fModel = s;
5009 if (s.BeginsWith(
"cpu MHz")) {
5010 TPRegexp(
"^.+: *([^ ]+).*").Substitute(s,
"$1");
5011 sysinfo->fCpuSpeed = s.Atoi();
5013 if (s.BeginsWith(
"cache size")) {
5014 TPRegexp(
"^.+: *([^ ]+).*").Substitute(s,
"$1");
5015 sysinfo->fL2Cache = s.Atoi();
5017 if (s.BeginsWith(
"processor")) {
5018 TPRegexp(
"^.+: *([^ ]+).*").Substitute(s,
"$1");
5019 sysinfo->fCpus = s.Atoi();
5026 f = fopen(
"/proc/meminfo",
"r");
5029 if (s.BeginsWith(
"MemTotal")) {
5030 TPRegexp(
"^.+: *([^ ]+).*").Substitute(s,
"$1");
5031 sysinfo->fPhysRam = (s.Atoi() / 1024);
5038 f = gSystem->OpenPipe(
"uname -s -p",
"r");
5042 s.Tokenize(sysinfo->fOS, from);
5043 s.Tokenize(sysinfo->fCpuType, from);
5044 gSystem->ClosePipe(f);
5051 static void ReadLinuxCpu(
long *ticks)
5053 ticks[0] = ticks[1] = ticks[2] = ticks[3] = 0;
5056 FILE *f = fopen(
"/proc/stat",
"r");
5060 sscanf(s.Data(),
"%*s %ld %ld %ld %ld", &ticks[0], &ticks[3], &ticks[1], &ticks[2]);
5068 static void GetLinuxCpuInfo(CpuInfo_t *cpuinfo, Int_t sampleTime)
5070 Double_t avg[3] = { -1., -1., -1. };
5072 if (getloadavg(avg,
sizeof(avg)) < 0) {
5073 ::Error(
"TUnixSystem::GetLinuxCpuInfo",
"getloadavg failed");
5077 cpuinfo->fLoad1m = (Float_t)avg[0];
5078 cpuinfo->fLoad5m = (Float_t)avg[1];
5079 cpuinfo->fLoad15m = (Float_t)avg[2];
5082 Long_t cpu_ticks1[4], cpu_ticks2[4];
5083 ReadLinuxCpu(cpu_ticks1);
5084 gSystem->Sleep(sampleTime);
5085 ReadLinuxCpu(cpu_ticks2);
5087 Long_t userticks = (cpu_ticks2[0] + cpu_ticks2[3]) -
5088 (cpu_ticks1[0] + cpu_ticks1[3]);
5089 Long_t systicks = cpu_ticks2[1] - cpu_ticks1[1];
5090 Long_t idleticks = cpu_ticks2[2] - cpu_ticks1[2];
5091 if (userticks < 0) userticks = 0;
5092 if (systicks < 0) systicks = 0;
5093 if (idleticks < 0) idleticks = 0;
5094 Long_t totalticks = userticks + systicks + idleticks;
5096 cpuinfo->fUser = ((Float_t)(100 * userticks)) / ((Float_t)totalticks);
5097 cpuinfo->fSys = ((Float_t)(100 * systicks)) / ((Float_t)totalticks);
5098 cpuinfo->fTotal = cpuinfo->fUser + cpuinfo->fSys;
5099 cpuinfo->fIdle = ((Float_t)(100 * idleticks)) / ((Float_t)totalticks);
5106 static void GetLinuxMemInfo(MemInfo_t *meminfo)
5109 FILE *f = fopen(
"/proc/meminfo",
"r");
5112 if (s.BeginsWith(
"MemTotal")) {
5113 TPRegexp(
"^.+: *([^ ]+).*").Substitute(s,
"$1");
5114 meminfo->fMemTotal = (s.Atoi() / 1024);
5116 if (s.BeginsWith(
"MemFree")) {
5117 TPRegexp(
"^.+: *([^ ]+).*").Substitute(s,
"$1");
5118 meminfo->fMemFree = (s.Atoi() / 1024);
5120 if (s.BeginsWith(
"SwapTotal")) {
5121 TPRegexp(
"^.+: *([^ ]+).*").Substitute(s,
"$1");
5122 meminfo->fSwapTotal = (s.Atoi() / 1024);
5124 if (s.BeginsWith(
"SwapFree")) {
5125 TPRegexp(
"^.+: *([^ ]+).*").Substitute(s,
"$1");
5126 meminfo->fSwapFree = (s.Atoi() / 1024);
5131 meminfo->fMemUsed = meminfo->fMemTotal - meminfo->fMemFree;
5132 meminfo->fSwapUsed = meminfo->fSwapTotal - meminfo->fSwapFree;
5138 static void GetLinuxProcInfo(ProcInfo_t *procinfo)
5141 if (getrusage(RUSAGE_SELF, &ru) < 0) {
5142 ::SysError(
"TUnixSystem::GetLinuxProcInfo",
"getrusage failed");
5144 procinfo->fCpuUser = (Float_t)(ru.ru_utime.tv_sec) +
5145 ((Float_t)(ru.ru_utime.tv_usec) / 1000000.);
5146 procinfo->fCpuSys = (Float_t)(ru.ru_stime.tv_sec) +
5147 ((Float_t)(ru.ru_stime.tv_usec) / 1000000.);
5150 procinfo->fMemVirtual = -1;
5151 procinfo->fMemResident = -1;
5153 FILE *f = fopen(TString::Format(
"/proc/%d/statm", gSystem->GetPid()),
"r");
5158 sscanf(s.Data(),
"%ld %ld", &total, &rss);
5159 procinfo->fMemVirtual = total * (getpagesize() / 1024);
5160 procinfo->fMemResident = rss * (getpagesize() / 1024);
5170 int TUnixSystem::GetSysInfo(SysInfo_t *info)
const
5172 if (!info)
return -1;
5174 static SysInfo_t sysinfo;
5176 if (!sysinfo.fCpus) {
5177 #if defined(R__MACOSX)
5178 GetDarwinSysInfo(&sysinfo);
5179 #elif defined(R__LINUX)
5180 GetLinuxSysInfo(&sysinfo);
5194 int TUnixSystem::GetCpuInfo(CpuInfo_t *info, Int_t sampleTime)
const
5196 if (!info)
return -1;
5198 #if defined(R__MACOSX)
5199 GetDarwinCpuInfo(info, sampleTime);
5200 #elif defined(R__LINUX)
5201 GetLinuxCpuInfo(info, sampleTime);
5211 int TUnixSystem::GetMemInfo(MemInfo_t *info)
const
5213 if (!info)
return -1;
5215 #if defined(R__MACOSX)
5216 GetDarwinMemInfo(info);
5217 #elif defined(R__LINUX)
5218 GetLinuxMemInfo(info);
5228 int TUnixSystem::GetProcInfo(ProcInfo_t *info)
const
5230 if (!info)
return -1;
5232 #if defined(R__MACOSX)
5233 GetDarwinProcInfo(info);
5234 #elif defined(R__LINUX)
5235 GetLinuxProcInfo(info);