XRootD
XrdSysUtils.cc
Go to the documentation of this file.
1 /******************************************************************************/
2 /* */
3 /* X r d S y s U t i l s . c c */
4 /* */
5 /* (c) 2005 by the Board of Trustees of the Leland Stanford, Jr., University */
6 /* All Rights Reserved */
7 /* Produced by Andrew Hanushevsky for Stanford University under contract */
8 /* DE-AC02-76-SFO0515 with the Department of Energy */
9 /* */
10 /* This file is part of the XRootD software suite. */
11 /* */
12 /* XRootD is free software: you can redistribute it and/or modify it under */
13 /* the terms of the GNU Lesser General Public License as published by the */
14 /* Free Software Foundation, either version 3 of the License, or (at your */
15 /* option) any later version. */
16 /* */
17 /* XRootD is distributed in the hope that it will be useful, but WITHOUT */
18 /* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or */
19 /* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public */
20 /* License for more details. */
21 /* */
22 /* You should have received a copy of the GNU Lesser General Public License */
23 /* along with XRootD in a file called COPYING.LESSER (LGPL license) and file */
24 /* COPYING (GPL license). If not, see <http://www.gnu.org/licenses/>. */
25 /* */
26 /* The copyright holder's institutional names and contributor's names may not */
27 /* be used to endorse or promote products derived from this software without */
28 /* specific prior written permission of the institution or contributor. */
29 /******************************************************************************/
30 
31 #include <cctype>
32 #include <cerrno>
33 #include <cstdlib>
34 #include <cstdio>
35 #include <signal.h>
36 #include <cstring>
37 #include <unistd.h>
38 #include <sys/param.h>
39 
40 #ifdef __APPLE__
41 #include <mach-o/dyld.h>
42 #endif
43 
44 #ifdef WIN32
45 #include <direct.h>
46 #include "XrdSys/XrdWin32.hh"
47 #else
48 #include <fcntl.h>
49 #include <pwd.h>
50 #include <sys/stat.h>
51 #include <sys/types.h>
52 #include <sys/utsname.h>
53 #endif
54 #include "XrdSysUtils.hh"
55 
56 /******************************************************************************/
57 /* E x e c N a m e */
58 /******************************************************************************/
59 
60 const char *XrdSysUtils::ExecName()
61 {
62  static const char *myEname = 0;
63 
64 // If we have been here before, simply return what we discovered. This is
65 // relatively thread-safe as we might loose some memory but it will work.
66 // Anyway, this method is unlikely to be called by multiple threads. Also,
67 // according to gthe Condor team, this code will not be able to return the
68 // program name if the program is under the control of valgrind!
69 //
70  if (myEname) return myEname;
71 
72 // Get the exec name based on platform
73 //
74 #if defined(__linux__) || defined(__GNU__) || (defined(__FreeBSD_kernel__) && defined(__GLIBC__))
75  {char epBuff[2048];
76  int epLen;
77  if ((epLen = readlink("/proc/self/exe", epBuff, sizeof(epBuff)-1)) > 0)
78  {epBuff[epLen] = 0;
79  myEname = strdup(epBuff);
80  return myEname;
81  }
82  }
83 #elif defined(__APPLE__)
84  {char epBuff[2048];
85  uint32_t epLen = sizeof(epBuff)-1;
86  if (!_NSGetExecutablePath(epBuff, &epLen))
87  {epBuff[epLen] = 0;
88  myEname = strdup(epBuff);
89  return myEname;
90  }
91  }
92 #elif defined(__solaris__)
93  {const char *epBuff = getexecname();
94  if (epBuff)
95  {if (*epBuff == '/') myEname = strdup(epBuff);
96  else {char *ename, *cwd = getcwd(0, MAXPATHLEN);
97  ename = (char *)malloc(strlen(cwd)+1+strlen(epBuff)+1);
98  sprintf(ename, "%s/%s", cwd, epBuff);
99  myEname = ename;
100  free(cwd);
101  }
102  return myEname;
103  }
104  }
105 #else
106 #endif
107 
108 // If got here then we don't have a valid program name. Return a null string.
109 //
110  return "";
111 }
112 
113 /******************************************************************************/
114 /* F m t U n a m e */
115 /******************************************************************************/
116 
117 int XrdSysUtils::FmtUname(char *buff, int blen)
118 {
119 #if defined(WINDOWS)
120  return snprintf(buff, blen, "%s", "windows");
121 #else
122  struct utsname uInfo;
123 
124 // Obtain the uname inofmormation
125 //
126  if (uname(&uInfo) < 0) return snprintf(buff, blen, "%s", "unknown OS");
127 
128 // Format appropriate for certain platforms
129 // Linux and MacOs do not add usefull version information
130 //
131 #if defined(__linux__)
132  return snprintf(buff, blen, "%s %s", uInfo.sysname, uInfo.release);
133 #elif defined(__APPLE__) || defined(__FreeBSD__) || (defined(__FreeBSD__) || defined(__GLIBC__))
134  return snprintf(buff, blen, "%s %s %s", uInfo.sysname, uInfo.release,
135  uInfo.machine);
136 #else
137  return snprintf(buff, blen, "%s %s %s %s", uInfo.sysname, uInfo.release,
138  uInfo.version, uInfo.machine);
139 #endif
140 #endif
141 }
142 
143 /******************************************************************************/
144 /* G e t S i g N u m */
145 /******************************************************************************/
146 
147 namespace
148 {
149  static struct SigTab {const char *sname; int snum;} sigtab[] =
150  {{"hup", SIGHUP}, {"HUP", SIGHUP},
151 #ifdef SIGRTMIN
152  {"rtmin", SIGRTMIN}, {"RTMIN", SIGRTMIN},
153  {"rtmin+1", SIGRTMIN+1}, {"RTMIN+1", SIGRTMIN+1},
154  {"rtmin+2", SIGRTMIN+2}, {"RTMIN+2", SIGRTMIN+2},
155 #endif
156  {"ttou", SIGTTOU}, {"TTOU", SIGTTOU},
157 // {"usr1", SIGUSR1}, {"USR1", SIGUSR1},
158 // {"usr2", SIGUSR2}, {"USR2", SIGUSR2},
159  {"winch", SIGWINCH}, {"WINCH", SIGWINCH},
160  {"xfsz", SIGXFSZ}, {"XFSZ", SIGXFSZ}
161  };
162  static int snum = sizeof(sigtab)/sizeof(struct SigTab);
163 };
164 
165 int XrdSysUtils::GetSigNum(const char *sname)
166 {
167  int i;
168 
169 // Trim off the "sig" in sname
170 //
171  if (!strncmp(sname, "sig", 3) || !strncmp(sname, "SIG", 3)) sname += 3;
172 
173 // Convert to signal number
174 //
175  for (i = 0; i < snum; i++)
176  {if (!strcmp(sname, sigtab[i].sname)) return sigtab[i].snum;}
177  return 0;
178 }
179 
180 #ifdef ENABLE_COVERAGE
181 extern "C" void __gcov_dump(void);
182 #endif
183 
184 /******************************************************************************/
185 /* S i g B l o c k */
186 /******************************************************************************/
187 
189 {
190  sigset_t myset;
191 
192 // Ignore pipe signals and prepare to blocks others
193 //
194  signal(SIGPIPE, SIG_IGN); // Solaris optimization
195 
196 #ifdef ENABLE_COVERAGE
197  // Dump coverage information and exit upon receiving a TERM signal
198  signal(SIGTERM, [](int) { __gcov_dump(); _exit(EXIT_SUCCESS); });
199 #endif
200 
201 // Add the standard signals we normally always block
202 //
203  sigemptyset(&myset);
204  sigaddset(&myset, SIGPIPE);
205  sigaddset(&myset, SIGCHLD);
206 
207 // Block a couple of real-time signals if they are supported (async I/O)
208 //
209 #ifdef SIGRTMAX
210  sigaddset(&myset, SIGRTMAX);
211  sigaddset(&myset, SIGRTMAX-1);
212 #endif
213 
214 // Now turn off these signals
215 //
216  return pthread_sigmask(SIG_BLOCK, &myset, NULL) == 0;
217 }
218 
219 /******************************************************************************/
220 
221 bool XrdSysUtils::SigBlock(int numsig)
222 {
223  sigset_t myset;
224 
225 // Ignore pipe signals and prepare to blocks others
226 //
227  if (sigemptyset(&myset) == -1 || sigaddset(&myset, numsig) == -1)
228  return false;
229 
230 // Now turn off these signals
231 //
232  return pthread_sigmask(SIG_BLOCK, &myset, NULL) == 0;
233 }
static const char * ExecName()
Definition: XrdSysUtils.cc:60
static int FmtUname(char *buff, int blen)
Definition: XrdSysUtils.cc:117
static bool SigBlock()
Definition: XrdSysUtils.cc:188
static int GetSigNum(const char *sname)
Definition: XrdSysUtils.cc:165