4 #include "config_portability.h"
6 #include <ctype.h> /* isspace() */
7 #include <errno.h> /* errno values */
8 #include <pwd.h> /* endpwent() getpwuid() */
9 #include <signal.h> /* sig{add,empty}set() sigprocmask() */
10 #include <stdio.h> /* file functions */
11 #include <stdlib.h> /* getenv() */
12 #include <string.h> /* memset() strchr() strlen() */
13 #include <unistd.h> /* alarm() getuid() sysconf() (where available) */
14 #include <sys/stat.h> /* stat() */
15 #include <sys/time.h> /* gettimeofday() */
16 #include <sys/types.h> /* size_t time_t */
17 #include <time.h> /* time() */
24 /* this is the lock for this module. Every other module will use a void *
25 * as a variable as mutex. */
26 pthread_mutex_t nwsLock = PTHREAD_MUTEX_INITIALIZER;
31 * These are defined here only becasue they are not found (sometimes) in
32 * the headers but only in libraries. To avoid annoying compilation warnings
38 int sigrelse(int sig);
46 # define SYSCONF_PROCESSOR_COUNT_PARAMETER _SC_CRAY_NCPU
47 # elif defined(_SC_NPROC_CONF)
48 # define SYSCONF_PROCESSOR_COUNT_PARAMETER _SC_NPROC_CONF
49 # elif defined(_SC_NPROCESSORS_CONF)
50 # define SYSCONF_PROCESSOR_COUNT_PARAMETER _SC_NPROCESSORS_CONF
52 # ifdef SYSCONF_PROCESSOR_COUNT_PARAMETER
53 /* Try to gracefully handle mis-configuration. */
54 int sysconfCount = sysconf(SYSCONF_PROCESSOR_COUNT_PARAMETER);
55 return (sysconfCount == 0) ? 1 : sysconfCount;
65 /* It should be thread safe (time should be thread safe) */
68 return((double)time(NULL));
73 GetEnvironmentValue(const char *name,
76 const char *defaultValue) {
84 static char rcLine[255 + 1];
86 const char *returnValue;
89 returnValue = getenv(name);
90 if(returnValue != NULL) {
91 /* easy way out: we got the environmental variable */
96 nameLen = strlen(name);
98 for(dirStart = rcDirs, dirEnd = dirStart; dirEnd != NULL; dirStart = dirEnd + 1) {
99 /* Construct a file path from the next dir in
100 * rcDirs and rcName. */
101 dirEnd = strchr(dirStart, ':');
102 memset(rcPath, '\0', sizeof(rcPath));
103 strncpy(rcPath, dirStart, (dirEnd == NULL) ? strlen(dirStart) : (dirEnd - dirStart));
104 if((strcmp(rcPath, "~") == 0) || (strcmp(rcPath, "~/") == 0)) {
105 homeDir = getenv("HOME");
106 if(homeDir != NULL) {
107 strcpy(rcPath, homeDir);
111 strcat(rcPath, rcName);
112 rcFile = fopen(rcPath, "r");
115 /* no luck, try the next one */
119 while(fgets(rcLine, sizeof(rcLine), rcFile) != NULL) {
120 /* Test against pattern " *#name# =". */
121 for(from = rcLine; (*from != '\0') && isspace((int)*from); from++)
122 ; /* Nothing more to do. */
123 if(strncmp(from, name, nameLen) != 0) {
126 for(from += nameLen; (*from != '\0') && isspace((int)*from); from++)
127 ; /* Nothing more to do. */
132 /* We found a line that sets the variable. */
133 (void)fclose(rcFile);
134 for(from++; (*from != '\0') && isspace((int)*from); from++)
135 ; /* Nothing more to do. */
137 /* Return a single word to allow for
138 * future free-format input. */
140 returnValue = from + 1;
141 for(from++, to = from; (*from != '\0') && (*from != '"'); from++, to++) {
173 for(to = from; (*to != '\0') && !isspace((int)*to); to++)
174 ; /* Nothing more to do. */
178 if (returnValue != NULL)
183 (void)fclose(rcFile);
186 return(defaultValue);
191 GetUserName(char *name,
193 struct passwd *myPasswd;
194 myPasswd = getpwuid(getuid());
195 if(myPasswd != NULL) {
196 strncpy(name, myPasswd->pw_name, length);
197 name[length - 1] = '\0';
200 return(myPasswd != NULL);
204 HoldSignal(int sig) {
210 sigaddset(&set, sig);\
211 sigprocmask(SIG_BLOCK, &set, &oset);
217 MakeDirectory(const char *path,
219 int makeEntirePath) {
221 const char *endSubPath;
222 struct stat pathStat;
223 char subPath[255 + 1];
226 endSubPath = path; /* This will ignore leading '/' */
227 while((endSubPath = strchr(endSubPath + 1, '/')) != NULL) {
228 memset(subPath, '\0', sizeof(subPath));
229 strncpy(subPath, path, endSubPath - path);
230 if((stat(subPath, &pathStat) == -1) && (errno == ENOENT)) {
231 if(mkdir(subPath, mode) == -1) {
235 else if(!S_ISDIR(pathStat.st_mode)) {
241 if((stat(path, &pathStat) == -1) && (errno == ENOENT)) {
242 return(mkdir(path, mode) != -1);
245 return(S_ISDIR(pathStat.st_mode));
252 GetNWSLock(void **lock) {
253 #ifdef HAVE_PTHREAD_H
260 /* let's play it safe: let's do one mutex at the time (in
261 * case multiple threads are running on the same lock */
262 if (pthread_mutex_lock(&nwsLock) != 0) {
265 /* there is no mutex yet: let's create it. We double
266 * check in the pretty rare condition of having 2 threads
267 * creating lock at the same time */
269 *lock = (void *)MALLOC(sizeof(pthread_mutex_t));
270 pthread_mutex_init((pthread_mutex_t *)(*lock), NULL);
272 if (*lock == NULL || pthread_mutex_unlock(&nwsLock) != 0) {
276 ret = pthread_mutex_lock((pthread_mutex_t *)(*lock));
278 fprintf(stderr, "GetNWSLock: Unable to lock (errno = %d)!\n", ret);
286 ReleaseNWSLock(void **lock) {
288 #ifdef HAVE_PTHREAD_H
289 if (lock == NULL || pthread_mutex_unlock((pthread_mutex_t *)*lock) != 0) {
299 gettimeofday(&tv, NULL);
300 return(tv.tv_sec * 1000000 + tv.tv_usec);
305 ReleaseSignal(int sig) {
311 sigaddset(&set, sig);
312 sigprocmask(SIG_UNBLOCK, &set, &oset);
318 SignalAlarm( handler h,
320 #ifdef USE_ALARM_SIGNAL
323 tmp = signal(SIGALRM, h);
324 if (tmp == SIG_ERR) {
334 /* It should be thread safe (alarm is thread safe) */
336 SetRealTimer(unsigned int numberOfSecs) {
337 #ifdef USE_ALARM_SIGNAL
338 #ifdef HAVE_SIGINTERRUPT
339 if (numberOfSecs > 0) {
340 /* just interrupt a system call upon receipt of interrupt */
341 siginterrupt(SIGALRM, 1);