xref: /freebsd/contrib/bmake/util.c (revision dba7b0ef928af88caa38728a73657b837aeeac93)
1*dba7b0efSSimon 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*dba7b0efSSimon J. Gerraty  *	$Id: util.c,v 1.46 2021/02/05 20:02:29 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 
16*dba7b0efSSimon 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 */
77*dba7b0efSSimon 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 	}
125*dba7b0efSSimon 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 
3433955d011SMarcel Moolenaar /* force posix signals */
344956e45f6SSimon J. Gerraty SignalProc
345956e45f6SSimon J. Gerraty bmake_signal(int s, SignalProc a)
3463955d011SMarcel Moolenaar {
3473955d011SMarcel Moolenaar 	struct sigaction sa, osa;
3483955d011SMarcel Moolenaar 
3493955d011SMarcel Moolenaar 	sa.sa_handler = a;
3503955d011SMarcel Moolenaar 	sigemptyset(&sa.sa_mask);
3513955d011SMarcel Moolenaar 	sa.sa_flags = SA_RESTART;
3523955d011SMarcel Moolenaar 
3533955d011SMarcel Moolenaar 	if (sigaction(s, &sa, &osa) == -1)
3543955d011SMarcel Moolenaar 		return SIG_ERR;
3553955d011SMarcel Moolenaar 	else
3563955d011SMarcel Moolenaar 		return osa.sa_handler;
3573955d011SMarcel Moolenaar }
3583955d011SMarcel Moolenaar 
3593955d011SMarcel Moolenaar #if !defined(HAVE_VSNPRINTF) || !defined(HAVE_VASPRINTF)
3603955d011SMarcel Moolenaar #include <stdarg.h>
3613955d011SMarcel Moolenaar #endif
3623955d011SMarcel Moolenaar 
3633955d011SMarcel Moolenaar #if !defined(HAVE_VSNPRINTF)
3643955d011SMarcel Moolenaar #if !defined(__osf__)
3653955d011SMarcel Moolenaar #ifdef _IOSTRG
3663955d011SMarcel Moolenaar #define STRFLAG	(_IOSTRG|_IOWRT)	/* no _IOWRT: avoid stdio bug */
3673955d011SMarcel Moolenaar #else
3683955d011SMarcel Moolenaar #if 0
3693955d011SMarcel Moolenaar #define STRFLAG	(_IOREAD)		/* XXX: Assume svr4 stdio */
3703955d011SMarcel Moolenaar #endif
3713955d011SMarcel Moolenaar #endif /* _IOSTRG */
3723955d011SMarcel Moolenaar #endif /* __osf__ */
3733955d011SMarcel Moolenaar 
3743955d011SMarcel Moolenaar int
3753955d011SMarcel Moolenaar vsnprintf(char *s, size_t n, const char *fmt, va_list args)
3763955d011SMarcel Moolenaar {
3773955d011SMarcel Moolenaar #ifdef STRFLAG
3783955d011SMarcel Moolenaar 	FILE fakebuf;
3793955d011SMarcel Moolenaar 
3803955d011SMarcel Moolenaar 	fakebuf._flag = STRFLAG;
3813955d011SMarcel Moolenaar 	/*
3823955d011SMarcel Moolenaar 	 * Some os's are char * _ptr, others are unsigned char *_ptr...
3833955d011SMarcel Moolenaar 	 * We cast to void * to make everyone happy.
3843955d011SMarcel Moolenaar 	 */
3853955d011SMarcel Moolenaar 	fakebuf._ptr = (void *)s;
3863955d011SMarcel Moolenaar 	fakebuf._cnt = n - 1;
3873955d011SMarcel Moolenaar 	fakebuf._file = -1;
3883955d011SMarcel Moolenaar 	_doprnt(fmt, args, &fakebuf);
3893955d011SMarcel Moolenaar 	fakebuf._cnt++;
3903955d011SMarcel Moolenaar 	putc('\0', &fakebuf);
3913955d011SMarcel Moolenaar 	if (fakebuf._cnt < 0)
3923955d011SMarcel Moolenaar 	    fakebuf._cnt = 0;
3933841c287SSimon J. Gerraty 	return n - fakebuf._cnt - 1;
3943955d011SMarcel Moolenaar #else
3953955d011SMarcel Moolenaar #ifndef _PATH_DEVNULL
3963955d011SMarcel Moolenaar # define _PATH_DEVNULL "/dev/null"
3973955d011SMarcel Moolenaar #endif
3983955d011SMarcel Moolenaar 	/*
3993955d011SMarcel Moolenaar 	 * Rats... we don't want to clobber anything...
4003955d011SMarcel Moolenaar 	 * do a printf to /dev/null to see how much space we need.
4013955d011SMarcel Moolenaar 	 */
4023955d011SMarcel Moolenaar 	static FILE *nullfp;
4033955d011SMarcel Moolenaar 	int need = 0;			/* XXX what's a useful error return? */
4043955d011SMarcel Moolenaar 
4053955d011SMarcel Moolenaar 	if (!nullfp)
4063955d011SMarcel Moolenaar 		nullfp = fopen(_PATH_DEVNULL, "w");
4073955d011SMarcel Moolenaar 	if (nullfp) {
4083955d011SMarcel Moolenaar 		need = vfprintf(nullfp, fmt, args);
4093955d011SMarcel Moolenaar 		if (need < n)
4103955d011SMarcel Moolenaar 			(void)vsprintf(s, fmt, args);
4113955d011SMarcel Moolenaar 	}
4123955d011SMarcel Moolenaar 	return need;
4133955d011SMarcel Moolenaar #endif
4143955d011SMarcel Moolenaar }
4153955d011SMarcel Moolenaar #endif
4163955d011SMarcel Moolenaar 
4173955d011SMarcel Moolenaar #if !defined(HAVE_SNPRINTF)
4183955d011SMarcel Moolenaar int
4193955d011SMarcel Moolenaar snprintf(char *s, size_t n, const char *fmt, ...)
4203955d011SMarcel Moolenaar {
4213955d011SMarcel Moolenaar 	va_list ap;
4223955d011SMarcel Moolenaar 	int rv;
4233955d011SMarcel Moolenaar 
4243955d011SMarcel Moolenaar 	va_start(ap, fmt);
4253955d011SMarcel Moolenaar 	rv = vsnprintf(s, n, fmt, ap);
4263955d011SMarcel Moolenaar 	va_end(ap);
4273955d011SMarcel Moolenaar 	return rv;
4283955d011SMarcel Moolenaar }
4293955d011SMarcel Moolenaar #endif
4303955d011SMarcel Moolenaar 
4313955d011SMarcel Moolenaar #if !defined(HAVE_STRFTIME)
4323955d011SMarcel Moolenaar size_t
4333955d011SMarcel Moolenaar strftime(char *buf, size_t len, const char *fmt, const struct tm *tm)
4343955d011SMarcel Moolenaar {
4353955d011SMarcel Moolenaar 	static char months[][4] = {
4363955d011SMarcel Moolenaar 		"Jan", "Feb", "Mar", "Apr", "May", "Jun",
4373955d011SMarcel Moolenaar 		"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
4383955d011SMarcel Moolenaar 	};
4393955d011SMarcel Moolenaar 
4403955d011SMarcel Moolenaar 	size_t s;
4413955d011SMarcel Moolenaar 	char *b = buf;
4423955d011SMarcel Moolenaar 
4433955d011SMarcel Moolenaar 	while (*fmt) {
4443955d011SMarcel Moolenaar 		if (len == 0)
4453955d011SMarcel Moolenaar 			return buf - b;
4463955d011SMarcel Moolenaar 		if (*fmt != '%') {
4473955d011SMarcel Moolenaar 			*buf++ = *fmt++;
4483955d011SMarcel Moolenaar 			len--;
4493955d011SMarcel Moolenaar 			continue;
4503955d011SMarcel Moolenaar 		}
4513955d011SMarcel Moolenaar 		switch (*fmt++) {
4523955d011SMarcel Moolenaar 		case '%':
4533955d011SMarcel Moolenaar 			*buf++ = '%';
4543955d011SMarcel Moolenaar 			len--;
4553955d011SMarcel Moolenaar 			if (len == 0) return buf - b;
4563955d011SMarcel Moolenaar 			/*FALLTHROUGH*/
4573955d011SMarcel Moolenaar 		case '\0':
4583955d011SMarcel Moolenaar 			*buf = '%';
4593955d011SMarcel Moolenaar 			s = 1;
4603955d011SMarcel Moolenaar 			break;
4613955d011SMarcel Moolenaar 		case 'k':
4623955d011SMarcel Moolenaar 			s = snprintf(buf, len, "%d", tm->tm_hour);
4633955d011SMarcel Moolenaar 			break;
4643955d011SMarcel Moolenaar 		case 'M':
4653955d011SMarcel Moolenaar 			s = snprintf(buf, len, "%02d", tm->tm_min);
4663955d011SMarcel Moolenaar 			break;
4673955d011SMarcel Moolenaar 		case 'S':
4683955d011SMarcel Moolenaar 			s = snprintf(buf, len, "%02d", tm->tm_sec);
4693955d011SMarcel Moolenaar 			break;
4703955d011SMarcel Moolenaar 		case 'b':
4713955d011SMarcel Moolenaar 			if (tm->tm_mon >= 12)
4723955d011SMarcel Moolenaar 				return buf - b;
4733955d011SMarcel Moolenaar 			s = snprintf(buf, len, "%s", months[tm->tm_mon]);
4743955d011SMarcel Moolenaar 			break;
4753955d011SMarcel Moolenaar 		case 'd':
4763955d011SMarcel Moolenaar 			s = snprintf(buf, len, "%02d", tm->tm_mday);
4773955d011SMarcel Moolenaar 			break;
4783955d011SMarcel Moolenaar 		case 'Y':
4793955d011SMarcel Moolenaar 			s = snprintf(buf, len, "%d", 1900 + tm->tm_year);
4803955d011SMarcel Moolenaar 			break;
4813955d011SMarcel Moolenaar 		default:
4823955d011SMarcel Moolenaar 			s = snprintf(buf, len, "Unsupported format %c",
4833955d011SMarcel Moolenaar 			    fmt[-1]);
4843955d011SMarcel Moolenaar 			break;
4853955d011SMarcel Moolenaar 		}
4863955d011SMarcel Moolenaar 		buf += s;
4873955d011SMarcel Moolenaar 		len -= s;
4883955d011SMarcel Moolenaar 	}
489956e45f6SSimon J. Gerraty 	return buf - b;
4903955d011SMarcel Moolenaar }
4913955d011SMarcel Moolenaar #endif
4923955d011SMarcel Moolenaar 
4933955d011SMarcel Moolenaar #if !defined(HAVE_KILLPG)
4943955d011SMarcel Moolenaar #if !defined(__hpux__) && !defined(__hpux)
4953955d011SMarcel Moolenaar int
4963955d011SMarcel Moolenaar killpg(int pid, int sig)
4973955d011SMarcel Moolenaar {
4983955d011SMarcel Moolenaar     return kill(-pid, sig);
4993955d011SMarcel Moolenaar }
5003955d011SMarcel Moolenaar #endif
5013955d011SMarcel Moolenaar #endif
5023955d011SMarcel Moolenaar 
5033955d011SMarcel Moolenaar #if !defined(HAVE_WARNX)
5043955d011SMarcel Moolenaar static void
5053955d011SMarcel Moolenaar vwarnx(const char *fmt, va_list args)
5063955d011SMarcel Moolenaar {
5073955d011SMarcel Moolenaar 	fprintf(stderr, "%s: ", progname);
5083955d011SMarcel Moolenaar 	if ((fmt)) {
5093955d011SMarcel Moolenaar 		vfprintf(stderr, fmt, args);
5103955d011SMarcel Moolenaar 		fprintf(stderr, ": ");
5113955d011SMarcel Moolenaar 	}
5123955d011SMarcel Moolenaar }
5133955d011SMarcel Moolenaar #endif
5143955d011SMarcel Moolenaar 
5153955d011SMarcel Moolenaar #if !defined(HAVE_WARN)
5163955d011SMarcel Moolenaar static void
5173955d011SMarcel Moolenaar vwarn(const char *fmt, va_list args)
5183955d011SMarcel Moolenaar {
5193955d011SMarcel Moolenaar 	vwarnx(fmt, args);
5203955d011SMarcel Moolenaar 	fprintf(stderr, "%s\n", strerror(errno));
5213955d011SMarcel Moolenaar }
5223955d011SMarcel Moolenaar #endif
5233955d011SMarcel Moolenaar 
5243955d011SMarcel Moolenaar #if !defined(HAVE_ERR)
5253955d011SMarcel Moolenaar static void
5263955d011SMarcel Moolenaar verr(int eval, const char *fmt, va_list args)
5273955d011SMarcel Moolenaar {
5283955d011SMarcel Moolenaar 	vwarn(fmt, args);
5293955d011SMarcel Moolenaar 	exit(eval);
5303955d011SMarcel Moolenaar }
5313955d011SMarcel Moolenaar #endif
5323955d011SMarcel Moolenaar 
5333955d011SMarcel Moolenaar #if !defined(HAVE_ERRX)
5343955d011SMarcel Moolenaar static void
5353955d011SMarcel Moolenaar verrx(int eval, const char *fmt, va_list args)
5363955d011SMarcel Moolenaar {
5373955d011SMarcel Moolenaar 	vwarnx(fmt, args);
5383955d011SMarcel Moolenaar 	exit(eval);
5393955d011SMarcel Moolenaar }
5403955d011SMarcel Moolenaar #endif
5413955d011SMarcel Moolenaar 
5423955d011SMarcel Moolenaar #if !defined(HAVE_ERR)
5433955d011SMarcel Moolenaar void
5443955d011SMarcel Moolenaar err(int eval, const char *fmt, ...)
5453955d011SMarcel Moolenaar {
5463955d011SMarcel Moolenaar         va_list ap;
5473955d011SMarcel Moolenaar 
5483955d011SMarcel Moolenaar         va_start(ap, fmt);
5493955d011SMarcel Moolenaar         verr(eval, fmt, ap);
5503955d011SMarcel Moolenaar         va_end(ap);
5513955d011SMarcel Moolenaar }
5523955d011SMarcel Moolenaar #endif
5533955d011SMarcel Moolenaar 
5543955d011SMarcel Moolenaar #if !defined(HAVE_ERRX)
5553955d011SMarcel Moolenaar void
5563955d011SMarcel Moolenaar errx(int eval, const char *fmt, ...)
5573955d011SMarcel Moolenaar {
5583955d011SMarcel Moolenaar         va_list ap;
5593955d011SMarcel Moolenaar 
5603955d011SMarcel Moolenaar         va_start(ap, fmt);
5613955d011SMarcel Moolenaar         verrx(eval, fmt, ap);
5623955d011SMarcel Moolenaar         va_end(ap);
5633955d011SMarcel Moolenaar }
5643955d011SMarcel Moolenaar #endif
5653955d011SMarcel Moolenaar 
5663955d011SMarcel Moolenaar #if !defined(HAVE_WARN)
5673955d011SMarcel Moolenaar void
5683955d011SMarcel Moolenaar warn(const char *fmt, ...)
5693955d011SMarcel Moolenaar {
5703955d011SMarcel Moolenaar         va_list ap;
5713955d011SMarcel Moolenaar 
5723955d011SMarcel Moolenaar         va_start(ap, fmt);
5733955d011SMarcel Moolenaar         vwarn(fmt, ap);
5743955d011SMarcel Moolenaar         va_end(ap);
5753955d011SMarcel Moolenaar }
5763955d011SMarcel Moolenaar #endif
5773955d011SMarcel Moolenaar 
5783955d011SMarcel Moolenaar #if !defined(HAVE_WARNX)
5793955d011SMarcel Moolenaar void
5803955d011SMarcel Moolenaar warnx(const char *fmt, ...)
5813955d011SMarcel Moolenaar {
5823955d011SMarcel Moolenaar         va_list ap;
5833955d011SMarcel Moolenaar 
5843955d011SMarcel Moolenaar         va_start(ap, fmt);
5853955d011SMarcel Moolenaar         vwarnx(fmt, ap);
5863955d011SMarcel Moolenaar         va_end(ap);
5873955d011SMarcel Moolenaar }
5883955d011SMarcel Moolenaar #endif
589