xref: /freebsd/contrib/bmake/util.c (revision 129043849f62f9cfa72f6fae68417d9995860f3f)
1dba7b0efSSimon J. Gerraty /*	$NetBSD: util.c,v 1.76 2021/02/03 08:00:36 rillig Exp $	*/
23955d011SMarcel Moolenaar 
33955d011SMarcel Moolenaar /*
43955d011SMarcel Moolenaar  * Missing stuff from OS's
53955d011SMarcel Moolenaar  *
6*12904384SSimon J. Gerraty  *	$Id: util.c,v 1.49 2021/10/14 19:26:52 sjg Exp $
73955d011SMarcel Moolenaar  */
83955d011SMarcel Moolenaar 
9956e45f6SSimon J. Gerraty #include <sys/param.h>
103955d011SMarcel Moolenaar #include <errno.h>
113955d011SMarcel Moolenaar #include <time.h>
123955d011SMarcel Moolenaar #include <signal.h>
133955d011SMarcel Moolenaar 
14956e45f6SSimon J. Gerraty #include "make.h"
15956e45f6SSimon J. Gerraty 
16dba7b0efSSimon J. Gerraty MAKE_RCSID("$NetBSD: util.c,v 1.76 2021/02/03 08:00:36 rillig Exp $");
17956e45f6SSimon J. Gerraty 
18956e45f6SSimon J. Gerraty #if !defined(MAKE_NATIVE) && !defined(HAVE_STRERROR)
193955d011SMarcel Moolenaar extern int errno, sys_nerr;
203955d011SMarcel Moolenaar extern char *sys_errlist[];
213955d011SMarcel Moolenaar 
223955d011SMarcel Moolenaar char *
233955d011SMarcel Moolenaar strerror(int e)
243955d011SMarcel Moolenaar {
253955d011SMarcel Moolenaar     static char buf[100];
263955d011SMarcel Moolenaar     if (e < 0 || e >= sys_nerr) {
27e2eeea75SSimon J. Gerraty 	snprintf(buf, sizeof buf, "Unknown error %d", e);
283955d011SMarcel Moolenaar 	return buf;
29e2eeea75SSimon J. Gerraty     } else
303955d011SMarcel Moolenaar 	return sys_errlist[e];
313955d011SMarcel Moolenaar }
323955d011SMarcel Moolenaar #endif
333955d011SMarcel Moolenaar 
343955d011SMarcel Moolenaar #if !defined(HAVE_GETENV) || !defined(HAVE_SETENV) || !defined(HAVE_UNSETENV)
353955d011SMarcel Moolenaar extern char **environ;
363955d011SMarcel Moolenaar 
373955d011SMarcel Moolenaar static char *
383955d011SMarcel Moolenaar findenv(const char *name, int *offset)
393955d011SMarcel Moolenaar {
403955d011SMarcel Moolenaar 	size_t i, len;
413955d011SMarcel Moolenaar 	char *p, *q;
423955d011SMarcel Moolenaar 
433955d011SMarcel Moolenaar 	len = strlen(name);
443955d011SMarcel Moolenaar 	for (i = 0; (q = environ[i]); i++) {
453955d011SMarcel Moolenaar 		p = strchr(q, '=');
463955d011SMarcel Moolenaar 		if (p == NULL || p - q != len)
473955d011SMarcel Moolenaar 			continue;
483955d011SMarcel Moolenaar 		if (strncmp(name, q, len) == 0) {
493955d011SMarcel Moolenaar 			*offset = i;
503955d011SMarcel Moolenaar 			return q + len + 1;
513955d011SMarcel Moolenaar 		}
523955d011SMarcel Moolenaar 	}
533955d011SMarcel Moolenaar 	*offset = i;
543955d011SMarcel Moolenaar 	return NULL;
553955d011SMarcel Moolenaar }
563955d011SMarcel Moolenaar 
573955d011SMarcel Moolenaar char *
583955d011SMarcel Moolenaar getenv(const char *name)
593955d011SMarcel Moolenaar {
603955d011SMarcel Moolenaar     int offset;
613955d011SMarcel Moolenaar 
623841c287SSimon J. Gerraty     return findenv(name, &offset);
633955d011SMarcel Moolenaar }
643955d011SMarcel Moolenaar 
653955d011SMarcel Moolenaar int
663955d011SMarcel Moolenaar unsetenv(const char *name)
673955d011SMarcel Moolenaar {
683955d011SMarcel Moolenaar 	char **p;
693955d011SMarcel Moolenaar 	int offset;
703955d011SMarcel Moolenaar 
713955d011SMarcel Moolenaar 	if (name == NULL || *name == '\0' || strchr(name, '=') != NULL) {
723955d011SMarcel Moolenaar 		errno = EINVAL;
733955d011SMarcel Moolenaar 		return -1;
743955d011SMarcel Moolenaar 	}
753955d011SMarcel Moolenaar 
763955d011SMarcel Moolenaar 	while (findenv(name, &offset))	{ /* if set multiple times */
77dba7b0efSSimon J. Gerraty 		for (p = &environ[offset];; p++)
783955d011SMarcel Moolenaar 			if (!(*p = *(p + 1)))
793955d011SMarcel Moolenaar 				break;
803955d011SMarcel Moolenaar 	}
813955d011SMarcel Moolenaar 	return 0;
823955d011SMarcel Moolenaar }
833955d011SMarcel Moolenaar 
843955d011SMarcel Moolenaar int
853955d011SMarcel Moolenaar setenv(const char *name, const char *value, int rewrite)
863955d011SMarcel Moolenaar {
873955d011SMarcel Moolenaar 	char *c, **newenv;
883955d011SMarcel Moolenaar 	const char *cc;
893955d011SMarcel Moolenaar 	size_t l_value, size;
903955d011SMarcel Moolenaar 	int offset;
913955d011SMarcel Moolenaar 
923955d011SMarcel Moolenaar 	if (name == NULL || value == NULL) {
933955d011SMarcel Moolenaar 		errno = EINVAL;
943955d011SMarcel Moolenaar 		return -1;
953955d011SMarcel Moolenaar 	}
963955d011SMarcel Moolenaar 
973955d011SMarcel Moolenaar 	if (*value == '=')			/* no `=' in value */
98e2eeea75SSimon J. Gerraty 		value++;
993955d011SMarcel Moolenaar 	l_value = strlen(value);
1003955d011SMarcel Moolenaar 
1013955d011SMarcel Moolenaar 	/* find if already exists */
1023955d011SMarcel Moolenaar 	if ((c = findenv(name, &offset))) {
1033955d011SMarcel Moolenaar 		if (!rewrite)
1043955d011SMarcel Moolenaar 			return 0;
1053955d011SMarcel Moolenaar 		if (strlen(c) >= l_value)	/* old larger; copy over */
1063955d011SMarcel Moolenaar 			goto copy;
1073955d011SMarcel Moolenaar 	} else {					/* create new slot */
1083955d011SMarcel Moolenaar 		size = sizeof(char *) * (offset + 2);
1093955d011SMarcel Moolenaar 		if (savedEnv == environ) {		/* just increase size */
1103955d011SMarcel Moolenaar 			if ((newenv = realloc(savedEnv, size)) == NULL)
1113955d011SMarcel Moolenaar 				return -1;
1123955d011SMarcel Moolenaar 			savedEnv = newenv;
1133955d011SMarcel Moolenaar 		} else {				/* get new space */
1143955d011SMarcel Moolenaar 			/*
1153955d011SMarcel Moolenaar 			 * We don't free here because we don't know if
1163955d011SMarcel Moolenaar 			 * the first allocation is valid on all OS's
1173955d011SMarcel Moolenaar 			 */
1183955d011SMarcel Moolenaar 			if ((savedEnv = malloc(size)) == NULL)
1193955d011SMarcel Moolenaar 				return -1;
1203955d011SMarcel Moolenaar 			(void)memcpy(savedEnv, environ, size - sizeof(char *));
1213955d011SMarcel Moolenaar 		}
1223955d011SMarcel Moolenaar 		environ = savedEnv;
1233955d011SMarcel Moolenaar 		environ[offset + 1] = NULL;
1243955d011SMarcel Moolenaar 	}
125dba7b0efSSimon J. Gerraty 	for (cc = name; *cc && *cc != '='; cc++)	/* no `=' in name */
1263955d011SMarcel Moolenaar 		continue;
1273955d011SMarcel Moolenaar 	size = cc - name;
1283955d011SMarcel Moolenaar 	/* name + `=' + value */
1293955d011SMarcel Moolenaar 	if ((environ[offset] = malloc(size + l_value + 2)) == NULL)
1303955d011SMarcel Moolenaar 		return -1;
1313955d011SMarcel Moolenaar 	c = environ[offset];
1323955d011SMarcel Moolenaar 	(void)memcpy(c, name, size);
1333955d011SMarcel Moolenaar 	c += size;
1343955d011SMarcel Moolenaar 	*c++ = '=';
1353955d011SMarcel Moolenaar copy:
1363955d011SMarcel Moolenaar 	(void)memcpy(c, value, l_value + 1);
1373955d011SMarcel Moolenaar 	return 0;
1383955d011SMarcel Moolenaar }
1393955d011SMarcel Moolenaar 
1403955d011SMarcel Moolenaar #ifdef TEST
1413955d011SMarcel Moolenaar int
1423955d011SMarcel Moolenaar main(int argc, char *argv[])
1433955d011SMarcel Moolenaar {
1443955d011SMarcel Moolenaar 	setenv(argv[1], argv[2], 0);
1453955d011SMarcel Moolenaar 	printf("%s\n", getenv(argv[1]));
1463955d011SMarcel Moolenaar 	unsetenv(argv[1]);
1473955d011SMarcel Moolenaar 	printf("%s\n", getenv(argv[1]));
1483955d011SMarcel Moolenaar 	return 0;
1493955d011SMarcel Moolenaar }
1503955d011SMarcel Moolenaar #endif
1513955d011SMarcel Moolenaar 
1523955d011SMarcel Moolenaar #endif
1533955d011SMarcel Moolenaar 
1543955d011SMarcel Moolenaar 
1553955d011SMarcel Moolenaar #if defined(__hpux__) || defined(__hpux)
15606b9b3e0SSimon J. Gerraty /*
15706b9b3e0SSimon J. Gerraty  * strrcpy():
1583955d011SMarcel Moolenaar  *	Like strcpy, going backwards and returning the new pointer
1593955d011SMarcel Moolenaar  */
1603955d011SMarcel Moolenaar static char *
1613955d011SMarcel Moolenaar strrcpy(char *ptr, char *str)
1623955d011SMarcel Moolenaar {
1633955d011SMarcel Moolenaar     int len = strlen(str);
1643955d011SMarcel Moolenaar 
16506b9b3e0SSimon J. Gerraty     while (len != 0)
1663955d011SMarcel Moolenaar 	*--ptr = str[--len];
1673955d011SMarcel Moolenaar 
1683841c287SSimon J. Gerraty     return ptr;
1693955d011SMarcel Moolenaar } /* end strrcpy */
1703955d011SMarcel Moolenaar 
1713955d011SMarcel Moolenaar 
1723955d011SMarcel Moolenaar char    *sys_siglist[] = {
1733955d011SMarcel Moolenaar 	"Signal 0",
1743955d011SMarcel Moolenaar 	"Hangup",			/* SIGHUP    */
1753955d011SMarcel Moolenaar 	"Interrupt",			/* SIGINT    */
1763955d011SMarcel Moolenaar 	"Quit",				/* SIGQUIT   */
1773955d011SMarcel Moolenaar 	"Illegal instruction",		/* SIGILL    */
1783955d011SMarcel Moolenaar 	"Trace/BPT trap",		/* SIGTRAP   */
1793955d011SMarcel Moolenaar 	"IOT trap",			/* SIGIOT    */
1803955d011SMarcel Moolenaar 	"EMT trap",			/* SIGEMT    */
1813955d011SMarcel Moolenaar 	"Floating point exception",	/* SIGFPE    */
1823955d011SMarcel Moolenaar 	"Killed",			/* SIGKILL   */
1833955d011SMarcel Moolenaar 	"Bus error",			/* SIGBUS    */
1843955d011SMarcel Moolenaar 	"Segmentation fault",		/* SIGSEGV   */
1853955d011SMarcel Moolenaar 	"Bad system call",		/* SIGSYS    */
1863955d011SMarcel Moolenaar 	"Broken pipe",			/* SIGPIPE   */
1873955d011SMarcel Moolenaar 	"Alarm clock",			/* SIGALRM   */
1883955d011SMarcel Moolenaar 	"Terminated",			/* SIGTERM   */
1893955d011SMarcel Moolenaar 	"User defined signal 1",	/* SIGUSR1   */
1903955d011SMarcel Moolenaar 	"User defined signal 2",	/* SIGUSR2   */
1913955d011SMarcel Moolenaar 	"Child exited",			/* SIGCLD    */
1923955d011SMarcel Moolenaar 	"Power-fail restart",		/* SIGPWR    */
1933955d011SMarcel Moolenaar 	"Virtual timer expired",	/* SIGVTALRM */
1943955d011SMarcel Moolenaar 	"Profiling timer expired",	/* SIGPROF   */
1953955d011SMarcel Moolenaar 	"I/O possible",			/* SIGIO     */
1963955d011SMarcel Moolenaar 	"Window size changes",		/* SIGWINDOW */
1973955d011SMarcel Moolenaar 	"Stopped (signal)",		/* SIGSTOP   */
1983955d011SMarcel Moolenaar 	"Stopped",			/* SIGTSTP   */
1993955d011SMarcel Moolenaar 	"Continued",			/* SIGCONT   */
2003955d011SMarcel Moolenaar 	"Stopped (tty input)",		/* SIGTTIN   */
2013955d011SMarcel Moolenaar 	"Stopped (tty output)",		/* SIGTTOU   */
2023955d011SMarcel Moolenaar 	"Urgent I/O condition",		/* SIGURG    */
2033955d011SMarcel Moolenaar 	"Remote lock lost (NFS)",	/* SIGLOST   */
2043955d011SMarcel Moolenaar 	"Signal 31",			/* reserved  */
2053955d011SMarcel Moolenaar 	"DIL signal"			/* SIGDIL    */
2063955d011SMarcel Moolenaar };
2073955d011SMarcel Moolenaar #endif /* __hpux__ || __hpux */
2083955d011SMarcel Moolenaar 
2093955d011SMarcel Moolenaar #if defined(__hpux__) || defined(__hpux)
2103955d011SMarcel Moolenaar #include <sys/types.h>
2113955d011SMarcel Moolenaar #include <sys/syscall.h>
2123955d011SMarcel Moolenaar #include <sys/signal.h>
2133955d011SMarcel Moolenaar #include <sys/stat.h>
2143955d011SMarcel Moolenaar #include <dirent.h>
2153955d011SMarcel Moolenaar #include <sys/time.h>
2163955d011SMarcel Moolenaar #include <unistd.h>
2173955d011SMarcel Moolenaar 
2183955d011SMarcel Moolenaar int
2193955d011SMarcel Moolenaar killpg(int pid, int sig)
2203955d011SMarcel Moolenaar {
2213955d011SMarcel Moolenaar     return kill(-pid, sig);
2223955d011SMarcel Moolenaar }
2233955d011SMarcel Moolenaar 
2243955d011SMarcel Moolenaar #if !defined(BSD) && !defined(d_fileno)
2253955d011SMarcel Moolenaar # define d_fileno d_ino
2263955d011SMarcel Moolenaar #endif
2273955d011SMarcel Moolenaar 
2283955d011SMarcel Moolenaar #ifndef DEV_DEV_COMPARE
2293955d011SMarcel Moolenaar # define DEV_DEV_COMPARE(a, b) ((a) == (b))
2303955d011SMarcel Moolenaar #endif
2313955d011SMarcel Moolenaar #define ISDOT(c) ((c)[0] == '.' && (((c)[1] == '\0') || ((c)[1] == '/')))
2323955d011SMarcel Moolenaar #define ISDOTDOT(c) ((c)[0] == '.' && ISDOT(&((c)[1])))
2333955d011SMarcel Moolenaar 
2343955d011SMarcel Moolenaar char *
2353955d011SMarcel Moolenaar getwd(char *pathname)
2363955d011SMarcel Moolenaar {
2373955d011SMarcel Moolenaar     DIR    *dp;
2383955d011SMarcel Moolenaar     struct dirent *d;
2393955d011SMarcel Moolenaar     extern int errno;
2403955d011SMarcel Moolenaar 
2413955d011SMarcel Moolenaar     struct stat st_root, st_cur, st_next, st_dotdot;
2423955d011SMarcel Moolenaar     char    pathbuf[MAXPATHLEN], nextpathbuf[MAXPATHLEN * 2];
2433955d011SMarcel Moolenaar     char   *pathptr, *nextpathptr, *cur_name_add;
2443955d011SMarcel Moolenaar 
2453955d011SMarcel Moolenaar     /* find the inode of root */
2463955d011SMarcel Moolenaar     if (stat("/", &st_root) == -1) {
2473955d011SMarcel Moolenaar 	(void)sprintf(pathname,
2483955d011SMarcel Moolenaar 			"getwd: Cannot stat \"/\" (%s)", strerror(errno));
2493955d011SMarcel Moolenaar 	return NULL;
2503955d011SMarcel Moolenaar     }
2513955d011SMarcel Moolenaar     pathbuf[MAXPATHLEN - 1] = '\0';
2523955d011SMarcel Moolenaar     pathptr = &pathbuf[MAXPATHLEN - 1];
2533955d011SMarcel Moolenaar     nextpathbuf[MAXPATHLEN - 1] = '\0';
2543955d011SMarcel Moolenaar     cur_name_add = nextpathptr = &nextpathbuf[MAXPATHLEN - 1];
2553955d011SMarcel Moolenaar 
2563955d011SMarcel Moolenaar     /* find the inode of the current directory */
2573955d011SMarcel Moolenaar     if (lstat(".", &st_cur) == -1) {
2583955d011SMarcel Moolenaar 	(void)sprintf(pathname,
2593955d011SMarcel Moolenaar 			"getwd: Cannot stat \".\" (%s)", strerror(errno));
2603955d011SMarcel Moolenaar 	return NULL;
2613955d011SMarcel Moolenaar     }
2623955d011SMarcel Moolenaar     nextpathptr = strrcpy(nextpathptr, "../");
2633955d011SMarcel Moolenaar 
2643955d011SMarcel Moolenaar     /* Descend to root */
2653955d011SMarcel Moolenaar     for (;;) {
2663955d011SMarcel Moolenaar 
2673955d011SMarcel Moolenaar 	/* look if we found root yet */
2683955d011SMarcel Moolenaar 	if (st_cur.st_ino == st_root.st_ino &&
2693955d011SMarcel Moolenaar 	    DEV_DEV_COMPARE(st_cur.st_dev, st_root.st_dev)) {
2703955d011SMarcel Moolenaar 	    (void)strcpy(pathname, *pathptr != '/' ? "/" : pathptr);
2713841c287SSimon J. Gerraty 	    return pathname;
2723955d011SMarcel Moolenaar 	}
2733955d011SMarcel Moolenaar 
2743955d011SMarcel Moolenaar 	/* open the parent directory */
2753955d011SMarcel Moolenaar 	if (stat(nextpathptr, &st_dotdot) == -1) {
2763955d011SMarcel Moolenaar 	    (void)sprintf(pathname,
2773955d011SMarcel Moolenaar 			    "getwd: Cannot stat directory \"%s\" (%s)",
2783955d011SMarcel Moolenaar 			    nextpathptr, strerror(errno));
2793955d011SMarcel Moolenaar 	    return NULL;
2803955d011SMarcel Moolenaar 	}
2813955d011SMarcel Moolenaar 	if ((dp = opendir(nextpathptr)) == NULL) {
2823955d011SMarcel Moolenaar 	    (void)sprintf(pathname,
2833955d011SMarcel Moolenaar 			    "getwd: Cannot open directory \"%s\" (%s)",
2843955d011SMarcel Moolenaar 			    nextpathptr, strerror(errno));
2853955d011SMarcel Moolenaar 	    return NULL;
2863955d011SMarcel Moolenaar 	}
2873955d011SMarcel Moolenaar 
2883955d011SMarcel Moolenaar 	/* look in the parent for the entry with the same inode */
2893955d011SMarcel Moolenaar 	if (DEV_DEV_COMPARE(st_dotdot.st_dev, st_cur.st_dev)) {
2903955d011SMarcel Moolenaar 	    /* Parent has same device. No need to stat every member */
2913955d011SMarcel Moolenaar 	    for (d = readdir(dp); d != NULL; d = readdir(dp))
2923955d011SMarcel Moolenaar 		if (d->d_fileno == st_cur.st_ino)
2933955d011SMarcel Moolenaar 		    break;
294e2eeea75SSimon J. Gerraty 	} else {
2953955d011SMarcel Moolenaar 	    /*
2963955d011SMarcel Moolenaar 	     * Parent has a different device. This is a mount point so we
2973955d011SMarcel Moolenaar 	     * need to stat every member
2983955d011SMarcel Moolenaar 	     */
2993955d011SMarcel Moolenaar 	    for (d = readdir(dp); d != NULL; d = readdir(dp)) {
3003955d011SMarcel Moolenaar 		if (ISDOT(d->d_name) || ISDOTDOT(d->d_name))
3013955d011SMarcel Moolenaar 		    continue;
3023955d011SMarcel Moolenaar 		(void)strcpy(cur_name_add, d->d_name);
3033955d011SMarcel Moolenaar 		if (lstat(nextpathptr, &st_next) == -1) {
3043955d011SMarcel Moolenaar 		    (void)sprintf(pathname,
3053955d011SMarcel Moolenaar 			"getwd: Cannot stat \"%s\" (%s)",
3063955d011SMarcel Moolenaar 			d->d_name, strerror(errno));
3073955d011SMarcel Moolenaar 		    (void)closedir(dp);
3083955d011SMarcel Moolenaar 		    return NULL;
3093955d011SMarcel Moolenaar 		}
3103955d011SMarcel Moolenaar 		/* check if we found it yet */
3113955d011SMarcel Moolenaar 		if (st_next.st_ino == st_cur.st_ino &&
3123955d011SMarcel Moolenaar 		    DEV_DEV_COMPARE(st_next.st_dev, st_cur.st_dev))
3133955d011SMarcel Moolenaar 		    break;
3143955d011SMarcel Moolenaar 	    }
3153955d011SMarcel Moolenaar 	}
3163955d011SMarcel Moolenaar 	if (d == NULL) {
3173955d011SMarcel Moolenaar 	    (void)sprintf(pathname,
3183955d011SMarcel Moolenaar 		"getwd: Cannot find \".\" in \"..\"");
3193955d011SMarcel Moolenaar 	    (void)closedir(dp);
3203955d011SMarcel Moolenaar 	    return NULL;
3213955d011SMarcel Moolenaar 	}
3223955d011SMarcel Moolenaar 	st_cur = st_dotdot;
3233955d011SMarcel Moolenaar 	pathptr = strrcpy(pathptr, d->d_name);
3243955d011SMarcel Moolenaar 	pathptr = strrcpy(pathptr, "/");
3253955d011SMarcel Moolenaar 	nextpathptr = strrcpy(nextpathptr, "../");
3263955d011SMarcel Moolenaar 	(void)closedir(dp);
3273955d011SMarcel Moolenaar 	*cur_name_add = '\0';
3283955d011SMarcel Moolenaar     }
3293955d011SMarcel Moolenaar } /* end getwd */
3303955d011SMarcel Moolenaar 
3313955d011SMarcel Moolenaar #endif /* __hpux */
3323955d011SMarcel Moolenaar 
3333955d011SMarcel Moolenaar #if !defined(HAVE_GETCWD)
3343955d011SMarcel Moolenaar char *
3353955d011SMarcel Moolenaar getcwd(path, sz)
3363955d011SMarcel Moolenaar      char *path;
3373955d011SMarcel Moolenaar      int sz;
3383955d011SMarcel Moolenaar {
3393955d011SMarcel Moolenaar 	return getwd(path);
3403955d011SMarcel Moolenaar }
3413955d011SMarcel Moolenaar #endif
3423955d011SMarcel Moolenaar 
343*12904384SSimon J. Gerraty #if !defined(HAVE_SIGACTION)
344*12904384SSimon J. Gerraty #include "sigact.h"
345*12904384SSimon J. Gerraty #endif
346*12904384SSimon J. Gerraty 
3473955d011SMarcel Moolenaar /* force posix signals */
348956e45f6SSimon J. Gerraty SignalProc
349956e45f6SSimon J. Gerraty bmake_signal(int s, SignalProc a)
3503955d011SMarcel Moolenaar {
3513955d011SMarcel Moolenaar 	struct sigaction sa, osa;
3523955d011SMarcel Moolenaar 
3533955d011SMarcel Moolenaar 	sa.sa_handler = a;
3543955d011SMarcel Moolenaar 	sigemptyset(&sa.sa_mask);
3553955d011SMarcel Moolenaar 	sa.sa_flags = SA_RESTART;
3563955d011SMarcel Moolenaar 
3573955d011SMarcel Moolenaar 	if (sigaction(s, &sa, &osa) == -1)
3583955d011SMarcel Moolenaar 		return SIG_ERR;
3593955d011SMarcel Moolenaar 	else
3603955d011SMarcel Moolenaar 		return osa.sa_handler;
3613955d011SMarcel Moolenaar }
3623955d011SMarcel Moolenaar 
3633955d011SMarcel Moolenaar #if !defined(HAVE_VSNPRINTF) || !defined(HAVE_VASPRINTF)
3643955d011SMarcel Moolenaar #include <stdarg.h>
3653955d011SMarcel Moolenaar #endif
3663955d011SMarcel Moolenaar 
3673955d011SMarcel Moolenaar #if !defined(HAVE_VSNPRINTF)
3683955d011SMarcel Moolenaar #if !defined(__osf__)
3693955d011SMarcel Moolenaar #ifdef _IOSTRG
3703955d011SMarcel Moolenaar #define STRFLAG	(_IOSTRG|_IOWRT)	/* no _IOWRT: avoid stdio bug */
3713955d011SMarcel Moolenaar #else
3723955d011SMarcel Moolenaar #if 0
3733955d011SMarcel Moolenaar #define STRFLAG	(_IOREAD)		/* XXX: Assume svr4 stdio */
3743955d011SMarcel Moolenaar #endif
3753955d011SMarcel Moolenaar #endif /* _IOSTRG */
3763955d011SMarcel Moolenaar #endif /* __osf__ */
3773955d011SMarcel Moolenaar 
3783955d011SMarcel Moolenaar int
3793955d011SMarcel Moolenaar vsnprintf(char *s, size_t n, const char *fmt, va_list args)
3803955d011SMarcel Moolenaar {
3813955d011SMarcel Moolenaar #ifdef STRFLAG
3823955d011SMarcel Moolenaar 	FILE fakebuf;
3833955d011SMarcel Moolenaar 
3843955d011SMarcel Moolenaar 	fakebuf._flag = STRFLAG;
3853955d011SMarcel Moolenaar 	/*
3863955d011SMarcel Moolenaar 	 * Some os's are char * _ptr, others are unsigned char *_ptr...
3873955d011SMarcel Moolenaar 	 * We cast to void * to make everyone happy.
3883955d011SMarcel Moolenaar 	 */
3893955d011SMarcel Moolenaar 	fakebuf._ptr = (void *)s;
3903955d011SMarcel Moolenaar 	fakebuf._cnt = n - 1;
3913955d011SMarcel Moolenaar 	fakebuf._file = -1;
3923955d011SMarcel Moolenaar 	_doprnt(fmt, args, &fakebuf);
3933955d011SMarcel Moolenaar 	fakebuf._cnt++;
3943955d011SMarcel Moolenaar 	putc('\0', &fakebuf);
3953955d011SMarcel Moolenaar 	if (fakebuf._cnt < 0)
3963955d011SMarcel Moolenaar 	    fakebuf._cnt = 0;
3973841c287SSimon J. Gerraty 	return n - fakebuf._cnt - 1;
3983955d011SMarcel Moolenaar #else
3993955d011SMarcel Moolenaar #ifndef _PATH_DEVNULL
4003955d011SMarcel Moolenaar # define _PATH_DEVNULL "/dev/null"
4013955d011SMarcel Moolenaar #endif
4023955d011SMarcel Moolenaar 	/*
4033955d011SMarcel Moolenaar 	 * Rats... we don't want to clobber anything...
4043955d011SMarcel Moolenaar 	 * do a printf to /dev/null to see how much space we need.
4053955d011SMarcel Moolenaar 	 */
4063955d011SMarcel Moolenaar 	static FILE *nullfp;
4073955d011SMarcel Moolenaar 	int need = 0;			/* XXX what's a useful error return? */
4083955d011SMarcel Moolenaar 
4093955d011SMarcel Moolenaar 	if (!nullfp)
4103955d011SMarcel Moolenaar 		nullfp = fopen(_PATH_DEVNULL, "w");
4113955d011SMarcel Moolenaar 	if (nullfp) {
4123955d011SMarcel Moolenaar 		need = vfprintf(nullfp, fmt, args);
4133955d011SMarcel Moolenaar 		if (need < n)
4143955d011SMarcel Moolenaar 			(void)vsprintf(s, fmt, args);
4153955d011SMarcel Moolenaar 	}
4163955d011SMarcel Moolenaar 	return need;
4173955d011SMarcel Moolenaar #endif
4183955d011SMarcel Moolenaar }
4193955d011SMarcel Moolenaar #endif
4203955d011SMarcel Moolenaar 
4213955d011SMarcel Moolenaar #if !defined(HAVE_SNPRINTF)
4223955d011SMarcel Moolenaar int
4233955d011SMarcel Moolenaar snprintf(char *s, size_t n, const char *fmt, ...)
4243955d011SMarcel Moolenaar {
4253955d011SMarcel Moolenaar 	va_list ap;
4263955d011SMarcel Moolenaar 	int rv;
4273955d011SMarcel Moolenaar 
4283955d011SMarcel Moolenaar 	va_start(ap, fmt);
4293955d011SMarcel Moolenaar 	rv = vsnprintf(s, n, fmt, ap);
4303955d011SMarcel Moolenaar 	va_end(ap);
4313955d011SMarcel Moolenaar 	return rv;
4323955d011SMarcel Moolenaar }
4333955d011SMarcel Moolenaar #endif
4343955d011SMarcel Moolenaar 
4353955d011SMarcel Moolenaar #if !defined(HAVE_STRFTIME)
4363955d011SMarcel Moolenaar size_t
4373955d011SMarcel Moolenaar strftime(char *buf, size_t len, const char *fmt, const struct tm *tm)
4383955d011SMarcel Moolenaar {
4393955d011SMarcel Moolenaar 	static char months[][4] = {
4403955d011SMarcel Moolenaar 		"Jan", "Feb", "Mar", "Apr", "May", "Jun",
4413955d011SMarcel Moolenaar 		"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
4423955d011SMarcel Moolenaar 	};
4433955d011SMarcel Moolenaar 
4443955d011SMarcel Moolenaar 	size_t s;
4453955d011SMarcel Moolenaar 	char *b = buf;
4463955d011SMarcel Moolenaar 
4473955d011SMarcel Moolenaar 	while (*fmt) {
4483955d011SMarcel Moolenaar 		if (len == 0)
4493955d011SMarcel Moolenaar 			return buf - b;
4503955d011SMarcel Moolenaar 		if (*fmt != '%') {
4513955d011SMarcel Moolenaar 			*buf++ = *fmt++;
4523955d011SMarcel Moolenaar 			len--;
4533955d011SMarcel Moolenaar 			continue;
4543955d011SMarcel Moolenaar 		}
4553955d011SMarcel Moolenaar 		switch (*fmt++) {
4563955d011SMarcel Moolenaar 		case '%':
4573955d011SMarcel Moolenaar 			*buf++ = '%';
4583955d011SMarcel Moolenaar 			len--;
4593955d011SMarcel Moolenaar 			if (len == 0) return buf - b;
4603955d011SMarcel Moolenaar 			/*FALLTHROUGH*/
4613955d011SMarcel Moolenaar 		case '\0':
4623955d011SMarcel Moolenaar 			*buf = '%';
4633955d011SMarcel Moolenaar 			s = 1;
4643955d011SMarcel Moolenaar 			break;
4653955d011SMarcel Moolenaar 		case 'k':
4663955d011SMarcel Moolenaar 			s = snprintf(buf, len, "%d", tm->tm_hour);
4673955d011SMarcel Moolenaar 			break;
4683955d011SMarcel Moolenaar 		case 'M':
4693955d011SMarcel Moolenaar 			s = snprintf(buf, len, "%02d", tm->tm_min);
4703955d011SMarcel Moolenaar 			break;
4713955d011SMarcel Moolenaar 		case 'S':
4723955d011SMarcel Moolenaar 			s = snprintf(buf, len, "%02d", tm->tm_sec);
4733955d011SMarcel Moolenaar 			break;
4743955d011SMarcel Moolenaar 		case 'b':
4753955d011SMarcel Moolenaar 			if (tm->tm_mon >= 12)
4763955d011SMarcel Moolenaar 				return buf - b;
4773955d011SMarcel Moolenaar 			s = snprintf(buf, len, "%s", months[tm->tm_mon]);
4783955d011SMarcel Moolenaar 			break;
4793955d011SMarcel Moolenaar 		case 'd':
4803955d011SMarcel Moolenaar 			s = snprintf(buf, len, "%02d", tm->tm_mday);
4813955d011SMarcel Moolenaar 			break;
4823955d011SMarcel Moolenaar 		case 'Y':
4833955d011SMarcel Moolenaar 			s = snprintf(buf, len, "%d", 1900 + tm->tm_year);
4843955d011SMarcel Moolenaar 			break;
4853955d011SMarcel Moolenaar 		default:
4863955d011SMarcel Moolenaar 			s = snprintf(buf, len, "Unsupported format %c",
4873955d011SMarcel Moolenaar 			    fmt[-1]);
4883955d011SMarcel Moolenaar 			break;
4893955d011SMarcel Moolenaar 		}
4903955d011SMarcel Moolenaar 		buf += s;
4913955d011SMarcel Moolenaar 		len -= s;
4923955d011SMarcel Moolenaar 	}
493956e45f6SSimon J. Gerraty 	return buf - b;
4943955d011SMarcel Moolenaar }
4953955d011SMarcel Moolenaar #endif
4963955d011SMarcel Moolenaar 
4973955d011SMarcel Moolenaar #if !defined(HAVE_KILLPG)
4983955d011SMarcel Moolenaar #if !defined(__hpux__) && !defined(__hpux)
4993955d011SMarcel Moolenaar int
5003955d011SMarcel Moolenaar killpg(int pid, int sig)
5013955d011SMarcel Moolenaar {
5023955d011SMarcel Moolenaar     return kill(-pid, sig);
5033955d011SMarcel Moolenaar }
5043955d011SMarcel Moolenaar #endif
5053955d011SMarcel Moolenaar #endif
5063955d011SMarcel Moolenaar 
5073955d011SMarcel Moolenaar #if !defined(HAVE_WARNX)
5083955d011SMarcel Moolenaar static void
5093955d011SMarcel Moolenaar vwarnx(const char *fmt, va_list args)
5103955d011SMarcel Moolenaar {
5113955d011SMarcel Moolenaar 	fprintf(stderr, "%s: ", progname);
5123955d011SMarcel Moolenaar 	if ((fmt)) {
5133955d011SMarcel Moolenaar 		vfprintf(stderr, fmt, args);
5143955d011SMarcel Moolenaar 		fprintf(stderr, ": ");
5153955d011SMarcel Moolenaar 	}
5163955d011SMarcel Moolenaar }
5173955d011SMarcel Moolenaar #endif
5183955d011SMarcel Moolenaar 
5193955d011SMarcel Moolenaar #if !defined(HAVE_WARN)
5203955d011SMarcel Moolenaar static void
5213955d011SMarcel Moolenaar vwarn(const char *fmt, va_list args)
5223955d011SMarcel Moolenaar {
5233955d011SMarcel Moolenaar 	vwarnx(fmt, args);
5243955d011SMarcel Moolenaar 	fprintf(stderr, "%s\n", strerror(errno));
5253955d011SMarcel Moolenaar }
5263955d011SMarcel Moolenaar #endif
5273955d011SMarcel Moolenaar 
5283955d011SMarcel Moolenaar #if !defined(HAVE_ERR)
5293955d011SMarcel Moolenaar static void
5303955d011SMarcel Moolenaar verr(int eval, const char *fmt, va_list args)
5313955d011SMarcel Moolenaar {
5323955d011SMarcel Moolenaar 	vwarn(fmt, args);
5333955d011SMarcel Moolenaar 	exit(eval);
5343955d011SMarcel Moolenaar }
5353955d011SMarcel Moolenaar #endif
5363955d011SMarcel Moolenaar 
5373955d011SMarcel Moolenaar #if !defined(HAVE_ERRX)
5383955d011SMarcel Moolenaar static void
5393955d011SMarcel Moolenaar verrx(int eval, const char *fmt, va_list args)
5403955d011SMarcel Moolenaar {
5413955d011SMarcel Moolenaar 	vwarnx(fmt, args);
5423955d011SMarcel Moolenaar 	exit(eval);
5433955d011SMarcel Moolenaar }
5443955d011SMarcel Moolenaar #endif
5453955d011SMarcel Moolenaar 
5463955d011SMarcel Moolenaar #if !defined(HAVE_ERR)
5473955d011SMarcel Moolenaar void
5483955d011SMarcel Moolenaar err(int eval, const char *fmt, ...)
5493955d011SMarcel Moolenaar {
5503955d011SMarcel Moolenaar         va_list ap;
5513955d011SMarcel Moolenaar 
5523955d011SMarcel Moolenaar         va_start(ap, fmt);
5533955d011SMarcel Moolenaar         verr(eval, fmt, ap);
5543955d011SMarcel Moolenaar         va_end(ap);
5553955d011SMarcel Moolenaar }
5563955d011SMarcel Moolenaar #endif
5573955d011SMarcel Moolenaar 
5583955d011SMarcel Moolenaar #if !defined(HAVE_ERRX)
5593955d011SMarcel Moolenaar void
5603955d011SMarcel Moolenaar errx(int eval, const char *fmt, ...)
5613955d011SMarcel Moolenaar {
5623955d011SMarcel Moolenaar         va_list ap;
5633955d011SMarcel Moolenaar 
5643955d011SMarcel Moolenaar         va_start(ap, fmt);
5653955d011SMarcel Moolenaar         verrx(eval, fmt, ap);
5663955d011SMarcel Moolenaar         va_end(ap);
5673955d011SMarcel Moolenaar }
5683955d011SMarcel Moolenaar #endif
5693955d011SMarcel Moolenaar 
5703955d011SMarcel Moolenaar #if !defined(HAVE_WARN)
5713955d011SMarcel Moolenaar void
5723955d011SMarcel Moolenaar warn(const char *fmt, ...)
5733955d011SMarcel Moolenaar {
5743955d011SMarcel Moolenaar         va_list ap;
5753955d011SMarcel Moolenaar 
5763955d011SMarcel Moolenaar         va_start(ap, fmt);
5773955d011SMarcel Moolenaar         vwarn(fmt, ap);
5783955d011SMarcel Moolenaar         va_end(ap);
5793955d011SMarcel Moolenaar }
5803955d011SMarcel Moolenaar #endif
5813955d011SMarcel Moolenaar 
5823955d011SMarcel Moolenaar #if !defined(HAVE_WARNX)
5833955d011SMarcel Moolenaar void
5843955d011SMarcel Moolenaar warnx(const char *fmt, ...)
5853955d011SMarcel Moolenaar {
5863955d011SMarcel Moolenaar         va_list ap;
5873955d011SMarcel Moolenaar 
5883955d011SMarcel Moolenaar         va_start(ap, fmt);
5893955d011SMarcel Moolenaar         vwarnx(fmt, ap);
5903955d011SMarcel Moolenaar         va_end(ap);
5913955d011SMarcel Moolenaar }
5923955d011SMarcel Moolenaar #endif
593*12904384SSimon J. Gerraty 
594*12904384SSimon J. Gerraty #ifdef HAVE_INTTYPES_H
595*12904384SSimon J. Gerraty #include <inttypes.h>
596*12904384SSimon J. Gerraty #elif defined(HAVE_STDINT_H)
597*12904384SSimon J. Gerraty #include <stdint.h>
598*12904384SSimon J. Gerraty #endif
599*12904384SSimon J. Gerraty #ifdef HAVE_LIMITS_H
600*12904384SSimon J. Gerraty #include <limits.h>
601*12904384SSimon J. Gerraty #endif
602*12904384SSimon J. Gerraty 
603*12904384SSimon J. Gerraty #ifndef NUM_TYPE
604*12904384SSimon J. Gerraty # ifdef HAVE_LONG_LONG_INT
605*12904384SSimon J. Gerraty #   define NUM_TYPE long long
606*12904384SSimon J. Gerraty # elif defined(_INT64_T_DECLARED) || defined(int64_t)
607*12904384SSimon J. Gerraty #   define NUM_TYPE int64_t
608*12904384SSimon J. Gerraty # endif
609*12904384SSimon J. Gerraty #endif
610*12904384SSimon J. Gerraty 
611*12904384SSimon J. Gerraty #ifdef NUM_TYPE
612*12904384SSimon J. Gerraty #if !defined(HAVE_STRTOLL)
613*12904384SSimon J. Gerraty #define BCS_ONLY
614*12904384SSimon J. Gerraty #define _FUNCNAME strtoll
615*12904384SSimon J. Gerraty #define __INT NUM_TYPE
616*12904384SSimon J. Gerraty #undef __INT_MIN
617*12904384SSimon J. Gerraty #undef __INT_MAX
618*12904384SSimon J. Gerraty #ifdef LLONG_MAX
619*12904384SSimon J. Gerraty # define __INT_MIN LLONG_MIN
620*12904384SSimon J. Gerraty # define __INT_MAX LLONG_MAX
621*12904384SSimon J. Gerraty #elif defined(INT64_MAX)
622*12904384SSimon J. Gerraty # define __INT_MIN INT64_MIN
623*12904384SSimon J. Gerraty # define __INT_MAX INT64_MAX
624*12904384SSimon J. Gerraty #endif
625*12904384SSimon J. Gerraty #ifndef _DIAGASSERT
626*12904384SSimon J. Gerraty # define _DIAGASSERT(e)
627*12904384SSimon J. Gerraty #endif
628*12904384SSimon J. Gerraty #ifndef __UNCONST
629*12904384SSimon J. Gerraty # define __UNCONST(a)      ((void *)(unsigned long)(const void *)(a))
630*12904384SSimon J. Gerraty #endif
631*12904384SSimon J. Gerraty #include "_strtol.h"
632*12904384SSimon J. Gerraty #endif
633*12904384SSimon J. Gerraty 
634*12904384SSimon J. Gerraty #endif
635*12904384SSimon J. Gerraty 
636*12904384SSimon J. Gerraty #if !defined(HAVE_STRTOL)
637*12904384SSimon J. Gerraty #define BCS_ONLY
638*12904384SSimon J. Gerraty #define _FUNCNAME strtol
639*12904384SSimon J. Gerraty #define __INT long
640*12904384SSimon J. Gerraty #undef __INT_MIN
641*12904384SSimon J. Gerraty #undef __INT_MAX
642*12904384SSimon J. Gerraty #define __INT_MIN LONG_MIN
643*12904384SSimon J. Gerraty #define __INT_MAX LONG_MAX
644*12904384SSimon J. Gerraty #ifndef _DIAGASSERT
645*12904384SSimon J. Gerraty # define _DIAGASSERT(e)
646*12904384SSimon J. Gerraty #endif
647*12904384SSimon J. Gerraty #ifndef __UNCONST
648*12904384SSimon J. Gerraty # define __UNCONST(a)      ((void *)(unsigned long)(const void *)(a))
649*12904384SSimon J. Gerraty #endif
650*12904384SSimon J. Gerraty #include "_strtol.h"
651*12904384SSimon J. Gerraty #endif
652*12904384SSimon J. Gerraty 
653*12904384SSimon J. Gerraty #if !defined(HAVE_STRTOUL)
654*12904384SSimon J. Gerraty #define BCS_ONLY
655*12904384SSimon J. Gerraty #define _FUNCNAME strtoul
656*12904384SSimon J. Gerraty #define __INT unsigned long
657*12904384SSimon J. Gerraty #undef __INT_MIN
658*12904384SSimon J. Gerraty #undef __INT_MAX
659*12904384SSimon J. Gerraty #define __INT_MIN 0
660*12904384SSimon J. Gerraty #define __INT_MAX ULONG_MAX
661*12904384SSimon J. Gerraty #ifndef _DIAGASSERT
662*12904384SSimon J. Gerraty # define _DIAGASSERT(e)
663*12904384SSimon J. Gerraty #endif
664*12904384SSimon J. Gerraty #ifndef __UNCONST
665*12904384SSimon J. Gerraty # define __UNCONST(a)      ((void *)(unsigned long)(const void *)(a))
666*12904384SSimon J. Gerraty #endif
667*12904384SSimon J. Gerraty #include "_strtol.h"
668*12904384SSimon J. Gerraty #endif
669