/******************************************************************************/
/* */
/* X r d S y s U t i l s . c c */
/* */
/* (c) 2005 by the Board of Trustees of the Leland Stanford, Jr., University */
/* All Rights Reserved */
/* Produced by Andrew Hanushevsky for Stanford University under contract */
/* DE-AC02-76-SFO0515 with the Department of Energy */
/* */
/* This file is part of the XRootD software suite. */
/* */
/* XRootD is free software: you can redistribute it and/or modify it under */
/* the terms of the GNU Lesser General Public License as published by the */
/* Free Software Foundation, either version 3 of the License, or (at your */
/* option) any later version. */
/* */
/* XRootD is distributed in the hope that it will be useful, but WITHOUT */
/* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or */
/* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public */
/* License for more details. */
/* */
/* You should have received a copy of the GNU Lesser General Public License */
/* along with XRootD in a file called COPYING.LESSER (LGPL license) and file */
/* COPYING (GPL license). If not, see . */
/* */
/* The copyright holder's institutional names and contributor's names may not */
/* be used to endorse or promote products derived from this software without */
/* specific prior written permission of the institution or contributor. */
/******************************************************************************/
#include
#include
#include
#include
#include
#include
#include
#include
#ifdef __APPLE__
#include
#endif
#ifdef WIN32
#include
#include "XrdSys/XrdWin32.hh"
#else
#include
#include
#include
#include
#include
#endif
#include "XrdSysUtils.hh"
/******************************************************************************/
/* E x e c N a m e */
/******************************************************************************/
const char *XrdSysUtils::ExecName()
{
static const char *myEname = 0;
// If we have been here before, simply return what we discovered. This is
// relatively thread-safe as we might loose some memory but it will work.
// Anyway, this method is unlikely to be called by multiple threads. Also,
// according to gthe Condor team, this code will not be able to return the
// program name if the program is under the control of valgrind!
//
if (myEname) return myEname;
// Get the exec name based on platform
//
#ifdef __linux__
{char epBuff[2048];
int epLen;
if ((epLen = readlink("/proc/self/exe", epBuff, sizeof(epBuff)-1)) > 0)
{epBuff[epLen] = 0;
myEname = strdup(epBuff);
return myEname;
}
}
#elif defined(__APPLE__)
{char epBuff[2048];
uint32_t epLen = sizeof(epBuff)-1;
if (!_NSGetExecutablePath(epBuff, &epLen))
{epBuff[epLen] = 0;
myEname = strdup(epBuff);
return myEname;
}
}
#elif defined(__solaris__)
{const char *epBuff = getexecname();
if (epBuff)
{if (*epBuff == '/') myEname = strdup(epBuff);
else {char *ename, *cwd = getcwd(0, MAXPATHLEN);
ename = (char *)malloc(strlen(cwd)+1+strlen(epBuff)+1);
sprintf(ename, "%s/%s", cwd, epBuff);
myEname = ename;
free(cwd);
}
return myEname;
}
}
#else
#endif
// If got here then we don't have a valid program name. Return a null string.
//
return "";
}
/******************************************************************************/
/* F m t U n a m e */
/******************************************************************************/
int XrdSysUtils::FmtUname(char *buff, int blen)
{
#if defined(WINDOWS)
return snprintf(buff, blen, "%s", "windows");
#else
struct utsname uInfo;
// Obtain the uname inofmormation
//
if (uname(&uInfo) < 0) return snprintf(buff, blen, "%s", "unknown OS");
// Format appropriate for certain platforms
// Linux and MacOs do not add usefull version information
//
#if defined(__linux__)
return snprintf(buff, blen, "%s %s", uInfo.sysname, uInfo.release);
#elif defined(__APPLE__) || defined(__FreeBSD__)
return snprintf(buff, blen, "%s %s %s", uInfo.sysname, uInfo.release,
uInfo.machine);
#else
return snprintf(buff, blen, "%s %s %s %s", uInfo.sysname, uInfo.release,
uInfo.version, uInfo.machine);
#endif
#endif
}
/******************************************************************************/
/* G e t S i g N u m */
/******************************************************************************/
namespace
{
static struct SigTab {const char *sname; int snum;} sigtab[] =
{{"hup", SIGHUP}, {"HUP", SIGHUP},
#ifdef SIGRTMIN
{"rtmin", SIGRTMIN}, {"RTMIN", SIGRTMIN},
{"rtmin+1", SIGRTMIN+1}, {"RTMIN+1", SIGRTMIN+1},
{"rtmin+2", SIGRTMIN+2}, {"RTMIN+2", SIGRTMIN+2},
#endif
{"ttou", SIGTTOU}, {"TTOU", SIGTTOU},
// {"usr1", SIGUSR1}, {"USR1", SIGUSR1},
// {"usr2", SIGUSR2}, {"USR2", SIGUSR2},
{"winch", SIGWINCH}, {"WINCH", SIGWINCH},
{"xfsz", SIGXFSZ}, {"XFSZ", SIGXFSZ}
};
static int snum = sizeof(sigtab)/sizeof(struct SigTab);
};
int XrdSysUtils::GetSigNum(const char *sname)
{
int i;
// Trim off the "sig" in sname
//
if (!strncmp(sname, "sig", 3) || !strncmp(sname, "SIG", 3)) sname += 3;
// Convert to signal number
//
for (i = 0; i < snum; i++)
{if (!strcmp(sname, sigtab[i].sname)) return sigtab[i].snum;}
return 0;
}
/******************************************************************************/
/* S i g B l o c k */
/******************************************************************************/
bool XrdSysUtils::SigBlock()
{
sigset_t myset;
// Ignore pipe signals and prepare to blocks others
//
signal(SIGPIPE, SIG_IGN); // Solaris optimization
// Add the standard signals we normally always block
//
sigemptyset(&myset);
sigaddset(&myset, SIGPIPE);
sigaddset(&myset, SIGCHLD);
// Block a couple of real-time signals if they are supported (async I/O)
//
#ifdef SIGRTMAX
sigaddset(&myset, SIGRTMAX);
sigaddset(&myset, SIGRTMAX-1);
#endif
// Now turn off these signals
//
return pthread_sigmask(SIG_BLOCK, &myset, NULL) == 0;
}
/******************************************************************************/
bool XrdSysUtils::SigBlock(int numsig)
{
sigset_t myset;
// Ignore pipe signals and prepare to blocks others
//
if (sigemptyset(&myset) == -1 || sigaddset(&myset, numsig) == -1)
return false;
// Now turn off these signals
//
return pthread_sigmask(SIG_BLOCK, &myset, NULL) == 0;
}