xref: /minix3/usr.bin/make/util.c (revision 84d9c625bfea59e274550651111ae9edfdc40fbd)
1*84d9c625SLionel Sambuc /*	$NetBSD: util.c,v 1.54 2013/11/26 13:44:41 joerg Exp $	*/
22e2caf59SThomas Veerman 
32e2caf59SThomas Veerman /*
42e2caf59SThomas Veerman  * Missing stuff from OS's
52e2caf59SThomas Veerman  */
6*84d9c625SLionel Sambuc #if defined(__MINT__) || defined(__linux__)
7*84d9c625SLionel Sambuc #include <signal.h>
8*84d9c625SLionel Sambuc #endif
92e2caf59SThomas Veerman 
102e2caf59SThomas Veerman #ifndef MAKE_NATIVE
11*84d9c625SLionel Sambuc static char rcsid[] = "$NetBSD: util.c,v 1.54 2013/11/26 13:44:41 joerg Exp $";
122e2caf59SThomas Veerman #else
132e2caf59SThomas Veerman #include <sys/cdefs.h>
142e2caf59SThomas Veerman #ifndef lint
15*84d9c625SLionel Sambuc __RCSID("$NetBSD: util.c,v 1.54 2013/11/26 13:44:41 joerg Exp $");
162e2caf59SThomas Veerman #endif
172e2caf59SThomas Veerman #endif
182e2caf59SThomas Veerman 
192e2caf59SThomas Veerman #include <sys/param.h>
202e2caf59SThomas Veerman 
212e2caf59SThomas Veerman #include <errno.h>
222e2caf59SThomas Veerman #include <stdio.h>
232e2caf59SThomas Veerman #include <time.h>
242e2caf59SThomas Veerman #include <signal.h>
252e2caf59SThomas Veerman 
262e2caf59SThomas Veerman #include "make.h"
272e2caf59SThomas Veerman 
282e2caf59SThomas Veerman #if !defined(MAKE_NATIVE) && !defined(HAVE_STRERROR)
292e2caf59SThomas Veerman extern int errno, sys_nerr;
302e2caf59SThomas Veerman extern char *sys_errlist[];
312e2caf59SThomas Veerman 
322e2caf59SThomas Veerman char *
strerror(int e)332e2caf59SThomas Veerman strerror(int e)
342e2caf59SThomas Veerman {
352e2caf59SThomas Veerman     static char buf[100];
362e2caf59SThomas Veerman     if (e < 0 || e >= sys_nerr) {
372e2caf59SThomas Veerman 	snprintf(buf, sizeof(buf), "Unknown error %d", e);
382e2caf59SThomas Veerman 	return buf;
392e2caf59SThomas Veerman     }
402e2caf59SThomas Veerman     else
412e2caf59SThomas Veerman 	return sys_errlist[e];
422e2caf59SThomas Veerman }
432e2caf59SThomas Veerman #endif
442e2caf59SThomas Veerman 
452e2caf59SThomas Veerman #if !defined(MAKE_NATIVE) && !defined(HAVE_SETENV)
462e2caf59SThomas Veerman extern char **environ;
472e2caf59SThomas Veerman 
482e2caf59SThomas Veerman static char *
findenv(const char * name,int * offset)492e2caf59SThomas Veerman findenv(const char *name, int *offset)
502e2caf59SThomas Veerman {
512e2caf59SThomas Veerman 	size_t i, len;
522e2caf59SThomas Veerman 	char *p, *q;
532e2caf59SThomas Veerman 
542bc7c627SLionel Sambuc 	len = strlen(name);
552e2caf59SThomas Veerman 	for (i = 0; (q = environ[i]); i++) {
562e2caf59SThomas Veerman 		p = strchr(q, '=');
572bc7c627SLionel Sambuc 		if (p == NULL || p - q != len)
582e2caf59SThomas Veerman 			continue;
592bc7c627SLionel Sambuc 		if (strncmp(name, q, len) == 0) {
602e2caf59SThomas Veerman 			*offset = i;
612e2caf59SThomas Veerman 			return q + len + 1;
622e2caf59SThomas Veerman 		}
632e2caf59SThomas Veerman 	}
642e2caf59SThomas Veerman 	*offset = i;
652e2caf59SThomas Veerman 	return NULL;
662e2caf59SThomas Veerman }
672e2caf59SThomas Veerman 
682bc7c627SLionel Sambuc char *
getenv(const char * name)692bc7c627SLionel Sambuc getenv(const char *name)
702bc7c627SLionel Sambuc {
712bc7c627SLionel Sambuc     int offset;
722bc7c627SLionel Sambuc 
732bc7c627SLionel Sambuc     return(findenv(name, &offset));
742bc7c627SLionel Sambuc }
752bc7c627SLionel Sambuc 
762e2caf59SThomas Veerman int
unsetenv(const char * name)772e2caf59SThomas Veerman unsetenv(const char *name)
782e2caf59SThomas Veerman {
792e2caf59SThomas Veerman 	char **p;
802e2caf59SThomas Veerman 	int offset;
812e2caf59SThomas Veerman 
822e2caf59SThomas Veerman 	if (name == NULL || *name == '\0' || strchr(name, '=') != NULL) {
832e2caf59SThomas Veerman 		errno = EINVAL;
842e2caf59SThomas Veerman 		return -1;
852e2caf59SThomas Veerman 	}
862e2caf59SThomas Veerman 
872e2caf59SThomas Veerman 	while (findenv(name, &offset))	{ /* if set multiple times */
882e2caf59SThomas Veerman 		for (p = &environ[offset];; ++p)
892e2caf59SThomas Veerman 			if (!(*p = *(p + 1)))
902e2caf59SThomas Veerman 				break;
912e2caf59SThomas Veerman 	}
922e2caf59SThomas Veerman 	return 0;
932e2caf59SThomas Veerman }
942e2caf59SThomas Veerman 
952e2caf59SThomas Veerman int
setenv(const char * name,const char * value,int rewrite)962e2caf59SThomas Veerman setenv(const char *name, const char *value, int rewrite)
972e2caf59SThomas Veerman {
982e2caf59SThomas Veerman 	char *c, **newenv;
992e2caf59SThomas Veerman 	const char *cc;
1002e2caf59SThomas Veerman 	size_t l_value, size;
1012e2caf59SThomas Veerman 	int offset;
1022e2caf59SThomas Veerman 
1032e2caf59SThomas Veerman 	if (name == NULL || value == NULL) {
1042e2caf59SThomas Veerman 		errno = EINVAL;
1052e2caf59SThomas Veerman 		return -1;
1062e2caf59SThomas Veerman 	}
1072e2caf59SThomas Veerman 
1082e2caf59SThomas Veerman 	if (*value == '=')			/* no `=' in value */
1092e2caf59SThomas Veerman 		++value;
1102e2caf59SThomas Veerman 	l_value = strlen(value);
1112e2caf59SThomas Veerman 
1122e2caf59SThomas Veerman 	/* find if already exists */
1132e2caf59SThomas Veerman 	if ((c = findenv(name, &offset))) {
1142e2caf59SThomas Veerman 		if (!rewrite)
1152e2caf59SThomas Veerman 			return 0;
1162e2caf59SThomas Veerman 		if (strlen(c) >= l_value)	/* old larger; copy over */
1172e2caf59SThomas Veerman 			goto copy;
1182e2caf59SThomas Veerman 	} else {					/* create new slot */
1192e2caf59SThomas Veerman 		size = sizeof(char *) * (offset + 2);
1202bc7c627SLionel Sambuc 		if (savedEnv == environ) {		/* just increase size */
1212bc7c627SLionel Sambuc 			if ((newenv = realloc(savedEnv, size)) == NULL)
1222e2caf59SThomas Veerman 				return -1;
1232bc7c627SLionel Sambuc 			savedEnv = newenv;
1242e2caf59SThomas Veerman 		} else {				/* get new space */
1252e2caf59SThomas Veerman 			/*
1262e2caf59SThomas Veerman 			 * We don't free here because we don't know if
1272e2caf59SThomas Veerman 			 * the first allocation is valid on all OS's
1282e2caf59SThomas Veerman 			 */
1292bc7c627SLionel Sambuc 			if ((savedEnv = malloc(size)) == NULL)
1302e2caf59SThomas Veerman 				return -1;
1312bc7c627SLionel Sambuc 			(void)memcpy(savedEnv, environ, size - sizeof(char *));
1322e2caf59SThomas Veerman 		}
1332bc7c627SLionel Sambuc 		environ = savedEnv;
1342e2caf59SThomas Veerman 		environ[offset + 1] = NULL;
1352e2caf59SThomas Veerman 	}
1362e2caf59SThomas Veerman 	for (cc = name; *cc && *cc != '='; ++cc)	/* no `=' in name */
1372e2caf59SThomas Veerman 		continue;
1382e2caf59SThomas Veerman 	size = cc - name;
1392e2caf59SThomas Veerman 	/* name + `=' + value */
1402e2caf59SThomas Veerman 	if ((environ[offset] = malloc(size + l_value + 2)) == NULL)
1412e2caf59SThomas Veerman 		return -1;
1422e2caf59SThomas Veerman 	c = environ[offset];
1432e2caf59SThomas Veerman 	(void)memcpy(c, name, size);
1442e2caf59SThomas Veerman 	c += size;
1452e2caf59SThomas Veerman 	*c++ = '=';
1462e2caf59SThomas Veerman copy:
1472e2caf59SThomas Veerman 	(void)memcpy(c, value, l_value + 1);
1482e2caf59SThomas Veerman 	return 0;
1492e2caf59SThomas Veerman }
1502e2caf59SThomas Veerman 
1512e2caf59SThomas Veerman #ifdef TEST
1522e2caf59SThomas Veerman int
main(int argc,char * argv[])1532e2caf59SThomas Veerman main(int argc, char *argv[])
1542e2caf59SThomas Veerman {
1552e2caf59SThomas Veerman 	setenv(argv[1], argv[2], 0);
1562e2caf59SThomas Veerman 	printf("%s\n", getenv(argv[1]));
1572e2caf59SThomas Veerman 	unsetenv(argv[1]);
1582e2caf59SThomas Veerman 	printf("%s\n", getenv(argv[1]));
1592e2caf59SThomas Veerman 	return 0;
1602e2caf59SThomas Veerman }
1612e2caf59SThomas Veerman #endif
1622e2caf59SThomas Veerman 
1632e2caf59SThomas Veerman #endif
1642e2caf59SThomas Veerman 
1652e2caf59SThomas Veerman #if defined(__hpux__) || defined(__hpux)
1662e2caf59SThomas Veerman /* strrcpy():
1672e2caf59SThomas Veerman  *	Like strcpy, going backwards and returning the new pointer
1682e2caf59SThomas Veerman  */
1692e2caf59SThomas Veerman static char *
strrcpy(char * ptr,char * str)1702e2caf59SThomas Veerman strrcpy(char *ptr, char *str)
1712e2caf59SThomas Veerman {
1722e2caf59SThomas Veerman     int len = strlen(str);
1732e2caf59SThomas Veerman 
1742e2caf59SThomas Veerman     while (len)
1752e2caf59SThomas Veerman 	*--ptr = str[--len];
1762e2caf59SThomas Veerman 
1772e2caf59SThomas Veerman     return (ptr);
1782e2caf59SThomas Veerman } /* end strrcpy */
1792e2caf59SThomas Veerman 
1802e2caf59SThomas Veerman char    *sys_siglist[] = {
1812e2caf59SThomas Veerman         "Signal 0",
1822e2caf59SThomas Veerman         "Hangup",                       /* SIGHUP    */
1832e2caf59SThomas Veerman         "Interrupt",                    /* SIGINT    */
1842e2caf59SThomas Veerman         "Quit",                         /* SIGQUIT   */
1852e2caf59SThomas Veerman         "Illegal instruction",          /* SIGILL    */
1862e2caf59SThomas Veerman         "Trace/BPT trap",               /* SIGTRAP   */
1872e2caf59SThomas Veerman         "IOT trap",                     /* SIGIOT    */
1882e2caf59SThomas Veerman         "EMT trap",                     /* SIGEMT    */
1892e2caf59SThomas Veerman         "Floating point exception",     /* SIGFPE    */
1902e2caf59SThomas Veerman         "Killed",                       /* SIGKILL   */
1912e2caf59SThomas Veerman         "Bus error",                    /* SIGBUS    */
1922e2caf59SThomas Veerman         "Segmentation fault",           /* SIGSEGV   */
1932e2caf59SThomas Veerman         "Bad system call",              /* SIGSYS    */
1942e2caf59SThomas Veerman         "Broken pipe",                  /* SIGPIPE   */
1952e2caf59SThomas Veerman         "Alarm clock",                  /* SIGALRM   */
1962e2caf59SThomas Veerman         "Terminated",                   /* SIGTERM   */
1972e2caf59SThomas Veerman         "User defined signal 1",        /* SIGUSR1   */
1982e2caf59SThomas Veerman         "User defined signal 2",        /* SIGUSR2   */
1992e2caf59SThomas Veerman         "Child exited",                 /* SIGCLD    */
2002e2caf59SThomas Veerman         "Power-fail restart",           /* SIGPWR    */
2012e2caf59SThomas Veerman         "Virtual timer expired",        /* SIGVTALRM */
2022e2caf59SThomas Veerman         "Profiling timer expired",      /* SIGPROF   */
2032e2caf59SThomas Veerman         "I/O possible",                 /* SIGIO     */
2042e2caf59SThomas Veerman         "Window size changes",          /* SIGWINDOW */
2052e2caf59SThomas Veerman         "Stopped (signal)",             /* SIGSTOP   */
2062e2caf59SThomas Veerman         "Stopped",                      /* SIGTSTP   */
2072e2caf59SThomas Veerman         "Continued",                    /* SIGCONT   */
2082e2caf59SThomas Veerman         "Stopped (tty input)",          /* SIGTTIN   */
2092e2caf59SThomas Veerman         "Stopped (tty output)",         /* SIGTTOU   */
2102e2caf59SThomas Veerman         "Urgent I/O condition",         /* SIGURG    */
2112e2caf59SThomas Veerman         "Remote lock lost (NFS)",       /* SIGLOST   */
2122e2caf59SThomas Veerman         "Signal 31",                    /* reserved  */
2132e2caf59SThomas Veerman         "DIL signal"                    /* SIGDIL    */
2142e2caf59SThomas Veerman };
2152e2caf59SThomas Veerman #endif /* __hpux__ || __hpux */
2162e2caf59SThomas Veerman 
2172e2caf59SThomas Veerman #if defined(__hpux__) || defined(__hpux)
2182e2caf59SThomas Veerman #include <sys/types.h>
2192e2caf59SThomas Veerman #include <sys/syscall.h>
2202e2caf59SThomas Veerman #include <sys/signal.h>
2212e2caf59SThomas Veerman #include <sys/stat.h>
2222e2caf59SThomas Veerman #include <dirent.h>
2232e2caf59SThomas Veerman #include <sys/time.h>
2242e2caf59SThomas Veerman #include <unistd.h>
2252e2caf59SThomas Veerman 
2262e2caf59SThomas Veerman int
killpg(int pid,int sig)2272e2caf59SThomas Veerman killpg(int pid, int sig)
2282e2caf59SThomas Veerman {
2292e2caf59SThomas Veerman     return kill(-pid, sig);
2302e2caf59SThomas Veerman }
2312e2caf59SThomas Veerman 
2322e2caf59SThomas Veerman #if !defined(__hpux__) && !defined(__hpux)
2332e2caf59SThomas Veerman void
srandom(long seed)2342e2caf59SThomas Veerman srandom(long seed)
2352e2caf59SThomas Veerman {
2362e2caf59SThomas Veerman     srand48(seed);
2372e2caf59SThomas Veerman }
2382e2caf59SThomas Veerman 
2392e2caf59SThomas Veerman long
random(void)2402e2caf59SThomas Veerman random(void)
2412e2caf59SThomas Veerman {
2422e2caf59SThomas Veerman     return lrand48();
2432e2caf59SThomas Veerman }
2442e2caf59SThomas Veerman #endif
2452e2caf59SThomas Veerman 
2462e2caf59SThomas Veerman #if !defined(__hpux__) && !defined(__hpux)
2472e2caf59SThomas Veerman int
utimes(char * file,struct timeval tvp[2])2482e2caf59SThomas Veerman utimes(char *file, struct timeval tvp[2])
2492e2caf59SThomas Veerman {
2502e2caf59SThomas Veerman     struct utimbuf t;
2512e2caf59SThomas Veerman 
2522e2caf59SThomas Veerman     t.actime  = tvp[0].tv_sec;
2532e2caf59SThomas Veerman     t.modtime = tvp[1].tv_sec;
2542e2caf59SThomas Veerman     return(utime(file, &t));
2552e2caf59SThomas Veerman }
2562e2caf59SThomas Veerman #endif
2572e2caf59SThomas Veerman 
2582e2caf59SThomas Veerman #if !defined(BSD) && !defined(d_fileno)
2592e2caf59SThomas Veerman # define d_fileno d_ino
2602e2caf59SThomas Veerman #endif
2612e2caf59SThomas Veerman 
2622e2caf59SThomas Veerman #ifndef DEV_DEV_COMPARE
2632e2caf59SThomas Veerman # define DEV_DEV_COMPARE(a, b) ((a) == (b))
2642e2caf59SThomas Veerman #endif
2652e2caf59SThomas Veerman #define ISDOT(c) ((c)[0] == '.' && (((c)[1] == '\0') || ((c)[1] == '/')))
2662e2caf59SThomas Veerman #define ISDOTDOT(c) ((c)[0] == '.' && ISDOT(&((c)[1])))
2672e2caf59SThomas Veerman 
2682e2caf59SThomas Veerman char *
getwd(char * pathname)2692e2caf59SThomas Veerman getwd(char *pathname)
2702e2caf59SThomas Veerman {
2712e2caf59SThomas Veerman     DIR    *dp;
2722e2caf59SThomas Veerman     struct dirent *d;
2732e2caf59SThomas Veerman     extern int errno;
2742e2caf59SThomas Veerman 
2752e2caf59SThomas Veerman     struct stat st_root, st_cur, st_next, st_dotdot;
2762e2caf59SThomas Veerman     char    pathbuf[MAXPATHLEN], nextpathbuf[MAXPATHLEN * 2];
2772e2caf59SThomas Veerman     char   *pathptr, *nextpathptr, *cur_name_add;
2782e2caf59SThomas Veerman 
2792e2caf59SThomas Veerman     /* find the inode of root */
2802e2caf59SThomas Veerman     if (stat("/", &st_root) == -1) {
2812e2caf59SThomas Veerman 	(void)sprintf(pathname,
2822e2caf59SThomas Veerman 			"getwd: Cannot stat \"/\" (%s)", strerror(errno));
2832e2caf59SThomas Veerman 	return NULL;
2842e2caf59SThomas Veerman     }
2852e2caf59SThomas Veerman     pathbuf[MAXPATHLEN - 1] = '\0';
2862e2caf59SThomas Veerman     pathptr = &pathbuf[MAXPATHLEN - 1];
2872e2caf59SThomas Veerman     nextpathbuf[MAXPATHLEN - 1] = '\0';
2882e2caf59SThomas Veerman     cur_name_add = nextpathptr = &nextpathbuf[MAXPATHLEN - 1];
2892e2caf59SThomas Veerman 
2902e2caf59SThomas Veerman     /* find the inode of the current directory */
2912e2caf59SThomas Veerman     if (lstat(".", &st_cur) == -1) {
2922e2caf59SThomas Veerman 	(void)sprintf(pathname,
2932e2caf59SThomas Veerman 			"getwd: Cannot stat \".\" (%s)", strerror(errno));
2942e2caf59SThomas Veerman 	return NULL;
2952e2caf59SThomas Veerman     }
2962e2caf59SThomas Veerman     nextpathptr = strrcpy(nextpathptr, "../");
2972e2caf59SThomas Veerman 
2982e2caf59SThomas Veerman     /* Descend to root */
2992e2caf59SThomas Veerman     for (;;) {
3002e2caf59SThomas Veerman 
3012e2caf59SThomas Veerman 	/* look if we found root yet */
3022e2caf59SThomas Veerman 	if (st_cur.st_ino == st_root.st_ino &&
3032e2caf59SThomas Veerman 	    DEV_DEV_COMPARE(st_cur.st_dev, st_root.st_dev)) {
3042e2caf59SThomas Veerman 	    (void)strcpy(pathname, *pathptr != '/' ? "/" : pathptr);
3052e2caf59SThomas Veerman 	    return (pathname);
3062e2caf59SThomas Veerman 	}
3072e2caf59SThomas Veerman 
3082e2caf59SThomas Veerman 	/* open the parent directory */
3092e2caf59SThomas Veerman 	if (stat(nextpathptr, &st_dotdot) == -1) {
3102e2caf59SThomas Veerman 	    (void)sprintf(pathname,
3112e2caf59SThomas Veerman 			    "getwd: Cannot stat directory \"%s\" (%s)",
3122e2caf59SThomas Veerman 			    nextpathptr, strerror(errno));
3132e2caf59SThomas Veerman 	    return NULL;
3142e2caf59SThomas Veerman 	}
3152e2caf59SThomas Veerman 	if ((dp = opendir(nextpathptr)) == NULL) {
3162e2caf59SThomas Veerman 	    (void)sprintf(pathname,
3172e2caf59SThomas Veerman 			    "getwd: Cannot open directory \"%s\" (%s)",
3182e2caf59SThomas Veerman 			    nextpathptr, strerror(errno));
3192e2caf59SThomas Veerman 	    return NULL;
3202e2caf59SThomas Veerman 	}
3212e2caf59SThomas Veerman 
3222e2caf59SThomas Veerman 	/* look in the parent for the entry with the same inode */
3232e2caf59SThomas Veerman 	if (DEV_DEV_COMPARE(st_dotdot.st_dev, st_cur.st_dev)) {
3242e2caf59SThomas Veerman 	    /* Parent has same device. No need to stat every member */
3252e2caf59SThomas Veerman 	    for (d = readdir(dp); d != NULL; d = readdir(dp))
3262e2caf59SThomas Veerman 		if (d->d_fileno == st_cur.st_ino)
3272e2caf59SThomas Veerman 		    break;
3282e2caf59SThomas Veerman 	}
3292e2caf59SThomas Veerman 	else {
3302e2caf59SThomas Veerman 	    /*
3312e2caf59SThomas Veerman 	     * Parent has a different device. This is a mount point so we
3322e2caf59SThomas Veerman 	     * need to stat every member
3332e2caf59SThomas Veerman 	     */
3342e2caf59SThomas Veerman 	    for (d = readdir(dp); d != NULL; d = readdir(dp)) {
3352e2caf59SThomas Veerman 		if (ISDOT(d->d_name) || ISDOTDOT(d->d_name))
3362e2caf59SThomas Veerman 		    continue;
3372e2caf59SThomas Veerman 		(void)strcpy(cur_name_add, d->d_name);
3382e2caf59SThomas Veerman 		if (lstat(nextpathptr, &st_next) == -1) {
3392e2caf59SThomas Veerman 		    (void)sprintf(pathname,
3402e2caf59SThomas Veerman 			"getwd: Cannot stat \"%s\" (%s)",
3412e2caf59SThomas Veerman 			d->d_name, strerror(errno));
3422e2caf59SThomas Veerman 		    (void)closedir(dp);
3432e2caf59SThomas Veerman 		    return NULL;
3442e2caf59SThomas Veerman 		}
3452e2caf59SThomas Veerman 		/* check if we found it yet */
3462e2caf59SThomas Veerman 		if (st_next.st_ino == st_cur.st_ino &&
3472e2caf59SThomas Veerman 		    DEV_DEV_COMPARE(st_next.st_dev, st_cur.st_dev))
3482e2caf59SThomas Veerman 		    break;
3492e2caf59SThomas Veerman 	    }
3502e2caf59SThomas Veerman 	}
3512e2caf59SThomas Veerman 	if (d == NULL) {
3522e2caf59SThomas Veerman 	    (void)sprintf(pathname,
3532e2caf59SThomas Veerman 		"getwd: Cannot find \".\" in \"..\"");
3542e2caf59SThomas Veerman 	    (void)closedir(dp);
3552e2caf59SThomas Veerman 	    return NULL;
3562e2caf59SThomas Veerman 	}
3572e2caf59SThomas Veerman 	st_cur = st_dotdot;
3582e2caf59SThomas Veerman 	pathptr = strrcpy(pathptr, d->d_name);
3592e2caf59SThomas Veerman 	pathptr = strrcpy(pathptr, "/");
3602e2caf59SThomas Veerman 	nextpathptr = strrcpy(nextpathptr, "../");
3612e2caf59SThomas Veerman 	(void)closedir(dp);
3622e2caf59SThomas Veerman 	*cur_name_add = '\0';
3632e2caf59SThomas Veerman     }
3642e2caf59SThomas Veerman } /* end getwd */
3652e2caf59SThomas Veerman #endif /* __hpux */
3662e2caf59SThomas Veerman 
3672e2caf59SThomas Veerman /* force posix signals */
3682e2caf59SThomas Veerman void (*
bmake_signal(int s,void (* a)(int))3692e2caf59SThomas Veerman bmake_signal(int s, void (*a)(int)))(int)
3702e2caf59SThomas Veerman {
3712e2caf59SThomas Veerman     struct sigaction sa, osa;
3722e2caf59SThomas Veerman 
3732e2caf59SThomas Veerman     sa.sa_handler = a;
3742e2caf59SThomas Veerman     sigemptyset(&sa.sa_mask);
3752e2caf59SThomas Veerman     sa.sa_flags = SA_RESTART;
3762e2caf59SThomas Veerman 
3772e2caf59SThomas Veerman     if (sigaction(s, &sa, &osa) == -1)
3782e2caf59SThomas Veerman 	return SIG_ERR;
3792e2caf59SThomas Veerman     else
3802e2caf59SThomas Veerman 	return osa.sa_handler;
3812e2caf59SThomas Veerman }
3822e2caf59SThomas Veerman 
3832e2caf59SThomas Veerman #if !defined(MAKE_NATIVE) && !defined(HAVE_VSNPRINTF)
3842e2caf59SThomas Veerman #include <stdarg.h>
3852e2caf59SThomas Veerman 
3862e2caf59SThomas Veerman #if !defined(__osf__)
3872e2caf59SThomas Veerman #ifdef _IOSTRG
3882e2caf59SThomas Veerman #define STRFLAG	(_IOSTRG|_IOWRT)	/* no _IOWRT: avoid stdio bug */
3892e2caf59SThomas Veerman #else
3902e2caf59SThomas Veerman #if 0
3912e2caf59SThomas Veerman #define STRFLAG	(_IOREAD)		/* XXX: Assume svr4 stdio */
3922e2caf59SThomas Veerman #endif
3932e2caf59SThomas Veerman #endif /* _IOSTRG */
3942e2caf59SThomas Veerman #endif /* __osf__ */
3952e2caf59SThomas Veerman 
3962e2caf59SThomas Veerman int
vsnprintf(char * s,size_t n,const char * fmt,va_list args)3972e2caf59SThomas Veerman vsnprintf(char *s, size_t n, const char *fmt, va_list args)
3982e2caf59SThomas Veerman {
3992e2caf59SThomas Veerman #ifdef STRFLAG
4002e2caf59SThomas Veerman 	FILE fakebuf;
4012e2caf59SThomas Veerman 
4022e2caf59SThomas Veerman 	fakebuf._flag = STRFLAG;
4032e2caf59SThomas Veerman 	/*
4042e2caf59SThomas Veerman 	 * Some os's are char * _ptr, others are unsigned char *_ptr...
4052e2caf59SThomas Veerman 	 * We cast to void * to make everyone happy.
4062e2caf59SThomas Veerman 	 */
4072e2caf59SThomas Veerman 	fakebuf._ptr = (void *)s;
4082e2caf59SThomas Veerman 	fakebuf._cnt = n-1;
4092e2caf59SThomas Veerman 	fakebuf._file = -1;
4102e2caf59SThomas Veerman 	_doprnt(fmt, args, &fakebuf);
4112e2caf59SThomas Veerman 	fakebuf._cnt++;
4122e2caf59SThomas Veerman 	putc('\0', &fakebuf);
4132e2caf59SThomas Veerman 	if (fakebuf._cnt<0)
4142e2caf59SThomas Veerman 	    fakebuf._cnt = 0;
4152e2caf59SThomas Veerman 	return (n-fakebuf._cnt-1);
4162e2caf59SThomas Veerman #else
4172e2caf59SThomas Veerman 	(void)vsprintf(s, fmt, args);
4182e2caf59SThomas Veerman 	return strlen(s);
4192e2caf59SThomas Veerman #endif
4202e2caf59SThomas Veerman }
4212e2caf59SThomas Veerman 
4222e2caf59SThomas Veerman int
snprintf(char * s,size_t n,const char * fmt,...)4232e2caf59SThomas Veerman snprintf(char *s, size_t n, const char *fmt, ...)
4242e2caf59SThomas Veerman {
4252e2caf59SThomas Veerman 	va_list ap;
4262e2caf59SThomas Veerman 	int rv;
4272e2caf59SThomas Veerman 
4282e2caf59SThomas Veerman 	va_start(ap, fmt);
4292e2caf59SThomas Veerman 	rv = vsnprintf(s, n, fmt, ap);
4302e2caf59SThomas Veerman 	va_end(ap);
4312e2caf59SThomas Veerman 	return rv;
4322e2caf59SThomas Veerman }
4332e2caf59SThomas Veerman 
4342e2caf59SThomas Veerman #if !defined(MAKE_NATIVE) && !defined(HAVE_STRFTIME)
4352e2caf59SThomas Veerman size_t
strftime(char * buf,size_t len,const char * fmt,const struct tm * tm)4362e2caf59SThomas Veerman strftime(char *buf, size_t len, const char *fmt, const struct tm *tm)
4372e2caf59SThomas Veerman {
4382e2caf59SThomas Veerman 	static char months[][4] = {
4392e2caf59SThomas Veerman 		"Jan", "Feb", "Mar", "Apr", "May", "Jun",
4402e2caf59SThomas Veerman 		"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
4412e2caf59SThomas Veerman 	};
4422e2caf59SThomas Veerman 
4432e2caf59SThomas Veerman 	size_t s;
4442e2caf59SThomas Veerman 	char *b = buf;
4452e2caf59SThomas Veerman 
4462e2caf59SThomas Veerman 	while (*fmt) {
4472e2caf59SThomas Veerman 		if (len == 0)
4482e2caf59SThomas Veerman 			return buf - b;
4492e2caf59SThomas Veerman 		if (*fmt != '%') {
4502e2caf59SThomas Veerman 			*buf++ = *fmt++;
4512e2caf59SThomas Veerman 			len--;
4522e2caf59SThomas Veerman 			continue;
4532e2caf59SThomas Veerman 		}
4542e2caf59SThomas Veerman 		switch (*fmt++) {
4552e2caf59SThomas Veerman 		case '%':
4562e2caf59SThomas Veerman 			*buf++ = '%';
4572e2caf59SThomas Veerman 			len--;
4582e2caf59SThomas Veerman 			if (len == 0) return buf - b;
4592e2caf59SThomas Veerman 			/*FALLTHROUGH*/
4602e2caf59SThomas Veerman 		case '\0':
4612e2caf59SThomas Veerman 			*buf = '%';
4622e2caf59SThomas Veerman 			s = 1;
4632e2caf59SThomas Veerman 			break;
4642e2caf59SThomas Veerman 		case 'k':
4652e2caf59SThomas Veerman 			s = snprintf(buf, len, "%d", tm->tm_hour);
4662e2caf59SThomas Veerman 			break;
4672e2caf59SThomas Veerman 		case 'M':
4682e2caf59SThomas Veerman 			s = snprintf(buf, len, "%02d", tm->tm_min);
4692e2caf59SThomas Veerman 			break;
4702e2caf59SThomas Veerman 		case 'S':
4712e2caf59SThomas Veerman 			s = snprintf(buf, len, "%02d", tm->tm_sec);
4722e2caf59SThomas Veerman 			break;
4732e2caf59SThomas Veerman 		case 'b':
4742e2caf59SThomas Veerman 			if (tm->tm_mon >= 12)
4752e2caf59SThomas Veerman 				return buf - b;
4762e2caf59SThomas Veerman 			s = snprintf(buf, len, "%s", months[tm->tm_mon]);
4772e2caf59SThomas Veerman 			break;
4782e2caf59SThomas Veerman 		case 'd':
4792e2caf59SThomas Veerman 			s = snprintf(buf, len, "%02d", tm->tm_mday);
4802e2caf59SThomas Veerman 			break;
4812e2caf59SThomas Veerman 		case 'Y':
4822e2caf59SThomas Veerman 			s = snprintf(buf, len, "%d", 1900 + tm->tm_year);
4832e2caf59SThomas Veerman 			break;
4842e2caf59SThomas Veerman 		default:
4852e2caf59SThomas Veerman 			s = snprintf(buf, len, "Unsupported format %c",
4862e2caf59SThomas Veerman 			    fmt[-1]);
4872e2caf59SThomas Veerman 			break;
4882e2caf59SThomas Veerman 		}
4892e2caf59SThomas Veerman 		buf += s;
4902e2caf59SThomas Veerman 		len -= s;
4912e2caf59SThomas Veerman 	}
4922e2caf59SThomas Veerman }
4932e2caf59SThomas Veerman #endif
4942e2caf59SThomas Veerman #endif
495