xref: /dragonfly/contrib/bmake/util.c (revision 6eef5f0c)
1*6eef5f0cSAntonio Huete Jimenez /*	$NetBSD: util.c,v 1.78 2021/12/15 12:58:01 rillig Exp $	*/
201e196c8SJohn Marino 
301e196c8SJohn Marino /*
401e196c8SJohn Marino  * Missing stuff from OS's
501e196c8SJohn Marino  *
6*6eef5f0cSAntonio Huete Jimenez  *	$Id: util.c,v 1.50 2021/12/21 18:47:24 sjg Exp $
701e196c8SJohn Marino  */
801e196c8SJohn Marino 
9a34d5fb1SAntonio Huete Jimenez #include <sys/param.h>
1001e196c8SJohn Marino #include <errno.h>
1101e196c8SJohn Marino #include <time.h>
1201e196c8SJohn Marino #include <signal.h>
1301e196c8SJohn Marino 
14a34d5fb1SAntonio Huete Jimenez #include "make.h"
15a34d5fb1SAntonio Huete Jimenez 
16*6eef5f0cSAntonio Huete Jimenez MAKE_RCSID("$NetBSD: util.c,v 1.78 2021/12/15 12:58:01 rillig Exp $");
17a34d5fb1SAntonio Huete Jimenez 
18a34d5fb1SAntonio Huete Jimenez #if !defined(MAKE_NATIVE) && !defined(HAVE_STRERROR)
1901e196c8SJohn Marino extern int errno, sys_nerr;
2001e196c8SJohn Marino extern char *sys_errlist[];
2101e196c8SJohn Marino 
2201e196c8SJohn Marino char *
strerror(int e)2301e196c8SJohn Marino strerror(int e)
2401e196c8SJohn Marino {
2501e196c8SJohn Marino 	static char buf[100];
2601e196c8SJohn Marino 	if (e < 0 || e >= sys_nerr) {
27a34d5fb1SAntonio Huete Jimenez 		snprintf(buf, sizeof buf, "Unknown error %d", e);
2801e196c8SJohn Marino 		return buf;
29a34d5fb1SAntonio Huete Jimenez 	} else
3001e196c8SJohn Marino 		return sys_errlist[e];
3101e196c8SJohn Marino }
3201e196c8SJohn Marino #endif
3301e196c8SJohn Marino 
3401e196c8SJohn Marino #if !defined(HAVE_GETENV) || !defined(HAVE_SETENV) || !defined(HAVE_UNSETENV)
3501e196c8SJohn Marino extern char **environ;
3601e196c8SJohn Marino 
3701e196c8SJohn Marino static char *
findenv(const char * name,int * offset)3801e196c8SJohn Marino findenv(const char *name, int *offset)
3901e196c8SJohn Marino {
4001e196c8SJohn Marino 	size_t i, len;
4101e196c8SJohn Marino 	char *p, *q;
4201e196c8SJohn Marino 
4301e196c8SJohn Marino 	len = strlen(name);
4401e196c8SJohn Marino 	for (i = 0; (q = environ[i]); i++) {
4501e196c8SJohn Marino 		p = strchr(q, '=');
4601e196c8SJohn Marino 		if (p == NULL || p - q != len)
4701e196c8SJohn Marino 			continue;
4801e196c8SJohn Marino 		if (strncmp(name, q, len) == 0) {
4901e196c8SJohn Marino 			*offset = i;
5001e196c8SJohn Marino 			return q + len + 1;
5101e196c8SJohn Marino 		}
5201e196c8SJohn Marino 	}
5301e196c8SJohn Marino 	*offset = i;
5401e196c8SJohn Marino 	return NULL;
5501e196c8SJohn Marino }
5601e196c8SJohn Marino 
5701e196c8SJohn Marino char *
getenv(const char * name)5801e196c8SJohn Marino getenv(const char *name)
5901e196c8SJohn Marino {
6001e196c8SJohn Marino 	int offset;
6101e196c8SJohn Marino 
62ca58f742SDaniel Fojt 	return findenv(name, &offset);
6301e196c8SJohn Marino }
6401e196c8SJohn Marino 
6501e196c8SJohn Marino int
unsetenv(const char * name)6601e196c8SJohn Marino unsetenv(const char *name)
6701e196c8SJohn Marino {
6801e196c8SJohn Marino 	char **p;
6901e196c8SJohn Marino 	int offset;
7001e196c8SJohn Marino 
7101e196c8SJohn Marino 	if (name == NULL || *name == '\0' || strchr(name, '=') != NULL) {
7201e196c8SJohn Marino 		errno = EINVAL;
7301e196c8SJohn Marino 		return -1;
7401e196c8SJohn Marino 	}
7501e196c8SJohn Marino 
7601e196c8SJohn Marino 	while (findenv(name, &offset)) {	/* if set multiple times */
77a34d5fb1SAntonio Huete Jimenez 		for (p = &environ[offset];; p++)
7801e196c8SJohn Marino 			if (!(*p = *(p + 1)))
7901e196c8SJohn Marino 				break;
8001e196c8SJohn Marino 	}
8101e196c8SJohn Marino 	return 0;
8201e196c8SJohn Marino }
8301e196c8SJohn Marino 
8401e196c8SJohn Marino int
setenv(const char * name,const char * value,int rewrite)8501e196c8SJohn Marino setenv(const char *name, const char *value, int rewrite)
8601e196c8SJohn Marino {
8701e196c8SJohn Marino 	char *c, **newenv;
8801e196c8SJohn Marino 	const char *cc;
8901e196c8SJohn Marino 	size_t l_value, size;
9001e196c8SJohn Marino 	int offset;
9101e196c8SJohn Marino 
9201e196c8SJohn Marino 	if (name == NULL || value == NULL) {
9301e196c8SJohn Marino 		errno = EINVAL;
9401e196c8SJohn Marino 		return -1;
9501e196c8SJohn Marino 	}
9601e196c8SJohn Marino 
9701e196c8SJohn Marino 	if (*value == '=')	/* no `=' in value */
98a34d5fb1SAntonio Huete Jimenez 		value++;
9901e196c8SJohn Marino 	l_value = strlen(value);
10001e196c8SJohn Marino 
10101e196c8SJohn Marino 	/* find if already exists */
10201e196c8SJohn Marino 	if ((c = findenv(name, &offset))) {
10301e196c8SJohn Marino 		if (!rewrite)
10401e196c8SJohn Marino 			return 0;
10501e196c8SJohn Marino 		if (strlen(c) >= l_value)	/* old larger; copy over */
10601e196c8SJohn Marino 			goto copy;
10701e196c8SJohn Marino 	} else {					/* create new slot */
10801e196c8SJohn Marino 		size = sizeof(char *) * (offset + 2);
10901e196c8SJohn Marino 		if (savedEnv == environ) {		/* just increase size */
11001e196c8SJohn Marino 			if ((newenv = realloc(savedEnv, size)) == NULL)
11101e196c8SJohn Marino 				return -1;
11201e196c8SJohn Marino 			savedEnv = newenv;
11301e196c8SJohn Marino 		} else {				/* get new space */
11401e196c8SJohn Marino 			/*
11501e196c8SJohn Marino 			 * We don't free here because we don't know if
11601e196c8SJohn Marino 			 * the first allocation is valid on all OS's
11701e196c8SJohn Marino 			 */
11801e196c8SJohn Marino 			if ((savedEnv = malloc(size)) == NULL)
11901e196c8SJohn Marino 				return -1;
12001e196c8SJohn Marino 			(void)memcpy(savedEnv, environ, size - sizeof(char *));
12101e196c8SJohn Marino 		}
12201e196c8SJohn Marino 		environ = savedEnv;
12301e196c8SJohn Marino 		environ[offset + 1] = NULL;
12401e196c8SJohn Marino 	}
125a34d5fb1SAntonio Huete Jimenez 	for (cc = name; *cc && *cc != '='; cc++)	/* no `=' in name */
12601e196c8SJohn Marino 		continue;
12701e196c8SJohn Marino 	size = cc - name;
12801e196c8SJohn Marino 	/* name + `=' + value */
12901e196c8SJohn Marino 	if ((environ[offset] = malloc(size + l_value + 2)) == NULL)
13001e196c8SJohn Marino 		return -1;
13101e196c8SJohn Marino 	c = environ[offset];
13201e196c8SJohn Marino 	(void)memcpy(c, name, size);
13301e196c8SJohn Marino 	c += size;
13401e196c8SJohn Marino 	*c++ = '=';
13501e196c8SJohn Marino copy:
13601e196c8SJohn Marino 	(void)memcpy(c, value, l_value + 1);
13701e196c8SJohn Marino 	return 0;
13801e196c8SJohn Marino }
13901e196c8SJohn Marino 
14001e196c8SJohn Marino #ifdef TEST
14101e196c8SJohn Marino int
main(int argc,char * argv[])14201e196c8SJohn Marino main(int argc, char *argv[])
14301e196c8SJohn Marino {
14401e196c8SJohn Marino 	setenv(argv[1], argv[2], 0);
14501e196c8SJohn Marino 	printf("%s\n", getenv(argv[1]));
14601e196c8SJohn Marino 	unsetenv(argv[1]);
14701e196c8SJohn Marino 	printf("%s\n", getenv(argv[1]));
14801e196c8SJohn Marino 	return 0;
14901e196c8SJohn Marino }
15001e196c8SJohn Marino #endif
15101e196c8SJohn Marino 
15201e196c8SJohn Marino #endif
15301e196c8SJohn Marino 
15401e196c8SJohn Marino 
15501e196c8SJohn Marino #if defined(__hpux__) || defined(__hpux)
156a34d5fb1SAntonio Huete Jimenez /*
157a34d5fb1SAntonio Huete Jimenez  * strrcpy():
15801e196c8SJohn Marino  *	Like strcpy, going backwards and returning the new pointer
15901e196c8SJohn Marino  */
16001e196c8SJohn Marino static char *
strrcpy(char * ptr,char * str)16101e196c8SJohn Marino strrcpy(char *ptr, char *str)
16201e196c8SJohn Marino {
16301e196c8SJohn Marino 	int len = strlen(str);
16401e196c8SJohn Marino 
165a34d5fb1SAntonio Huete Jimenez 	while (len != 0)
16601e196c8SJohn Marino 		*--ptr = str[--len];
16701e196c8SJohn Marino 
168ca58f742SDaniel Fojt 	return ptr;
169*6eef5f0cSAntonio Huete Jimenez }
17001e196c8SJohn Marino 
17101e196c8SJohn Marino char *sys_siglist[] = {
17201e196c8SJohn Marino 	"Signal 0",
17301e196c8SJohn Marino 	"Hangup",			/* SIGHUP    */
17401e196c8SJohn Marino 	"Interrupt",			/* SIGINT    */
17501e196c8SJohn Marino 	"Quit",				/* SIGQUIT   */
17601e196c8SJohn Marino 	"Illegal instruction",		/* SIGILL    */
17701e196c8SJohn Marino 	"Trace/BPT trap",		/* SIGTRAP   */
17801e196c8SJohn Marino 	"IOT trap",			/* SIGIOT    */
17901e196c8SJohn Marino 	"EMT trap",			/* SIGEMT    */
18001e196c8SJohn Marino 	"Floating point exception",	/* SIGFPE    */
18101e196c8SJohn Marino 	"Killed",			/* SIGKILL   */
18201e196c8SJohn Marino 	"Bus error",			/* SIGBUS    */
18301e196c8SJohn Marino 	"Segmentation fault",		/* SIGSEGV   */
18401e196c8SJohn Marino 	"Bad system call",		/* SIGSYS    */
18501e196c8SJohn Marino 	"Broken pipe",			/* SIGPIPE   */
18601e196c8SJohn Marino 	"Alarm clock",			/* SIGALRM   */
18701e196c8SJohn Marino 	"Terminated",			/* SIGTERM   */
18801e196c8SJohn Marino 	"User defined signal 1",	/* SIGUSR1   */
18901e196c8SJohn Marino 	"User defined signal 2",	/* SIGUSR2   */
19001e196c8SJohn Marino 	"Child exited",			/* SIGCLD    */
19101e196c8SJohn Marino 	"Power-fail restart",		/* SIGPWR    */
19201e196c8SJohn Marino 	"Virtual timer expired",	/* SIGVTALRM */
19301e196c8SJohn Marino 	"Profiling timer expired",	/* SIGPROF   */
19401e196c8SJohn Marino 	"I/O possible",			/* SIGIO     */
19501e196c8SJohn Marino 	"Window size changes",		/* SIGWINDOW */
19601e196c8SJohn Marino 	"Stopped (signal)",		/* SIGSTOP   */
19701e196c8SJohn Marino 	"Stopped",			/* SIGTSTP   */
19801e196c8SJohn Marino 	"Continued",			/* SIGCONT   */
19901e196c8SJohn Marino 	"Stopped (tty input)",		/* SIGTTIN   */
20001e196c8SJohn Marino 	"Stopped (tty output)",		/* SIGTTOU   */
20101e196c8SJohn Marino 	"Urgent I/O condition",		/* SIGURG    */
20201e196c8SJohn Marino 	"Remote lock lost (NFS)",	/* SIGLOST   */
20301e196c8SJohn Marino 	"Signal 31",			/* reserved  */
20401e196c8SJohn Marino 	"DIL signal"			/* SIGDIL    */
20501e196c8SJohn Marino };
20601e196c8SJohn Marino #endif /* __hpux__ || __hpux */
20701e196c8SJohn Marino 
20801e196c8SJohn Marino #if defined(__hpux__) || defined(__hpux)
20901e196c8SJohn Marino #include <sys/types.h>
21001e196c8SJohn Marino #include <sys/syscall.h>
21101e196c8SJohn Marino #include <sys/signal.h>
21201e196c8SJohn Marino #include <sys/stat.h>
21301e196c8SJohn Marino #include <dirent.h>
21401e196c8SJohn Marino #include <sys/time.h>
21501e196c8SJohn Marino #include <unistd.h>
21601e196c8SJohn Marino 
21701e196c8SJohn Marino int
killpg(int pid,int sig)21801e196c8SJohn Marino killpg(int pid, int sig)
21901e196c8SJohn Marino {
22001e196c8SJohn Marino 	return kill(-pid, sig);
22101e196c8SJohn Marino }
22201e196c8SJohn Marino 
22301e196c8SJohn Marino #if !defined(BSD) && !defined(d_fileno)
22401e196c8SJohn Marino # define d_fileno d_ino
22501e196c8SJohn Marino #endif
22601e196c8SJohn Marino 
22701e196c8SJohn Marino #ifndef DEV_DEV_COMPARE
22801e196c8SJohn Marino # define DEV_DEV_COMPARE(a, b) ((a) == (b))
22901e196c8SJohn Marino #endif
23001e196c8SJohn Marino #define ISDOT(c) ((c)[0] == '.' && (((c)[1] == '\0') || ((c)[1] == '/')))
23101e196c8SJohn Marino #define ISDOTDOT(c) ((c)[0] == '.' && ISDOT(&((c)[1])))
23201e196c8SJohn Marino 
23301e196c8SJohn Marino char *
getwd(char * pathname)23401e196c8SJohn Marino getwd(char *pathname)
23501e196c8SJohn Marino {
23601e196c8SJohn Marino     DIR    *dp;
23701e196c8SJohn Marino     struct dirent *d;
23801e196c8SJohn Marino     extern int errno;
23901e196c8SJohn Marino 
24001e196c8SJohn Marino     struct stat st_root, st_cur, st_next, st_dotdot;
24101e196c8SJohn Marino     char    pathbuf[MAXPATHLEN], nextpathbuf[MAXPATHLEN * 2];
24201e196c8SJohn Marino     char   *pathptr, *nextpathptr, *cur_name_add;
24301e196c8SJohn Marino 
24401e196c8SJohn Marino     /* find the inode of root */
24501e196c8SJohn Marino     if (stat("/", &st_root) == -1) {
24601e196c8SJohn Marino 	(void)sprintf(pathname,
24701e196c8SJohn Marino 			"getwd: Cannot stat \"/\" (%s)", strerror(errno));
24801e196c8SJohn Marino 	return NULL;
24901e196c8SJohn Marino     }
25001e196c8SJohn Marino     pathbuf[MAXPATHLEN - 1] = '\0';
25101e196c8SJohn Marino     pathptr = &pathbuf[MAXPATHLEN - 1];
25201e196c8SJohn Marino     nextpathbuf[MAXPATHLEN - 1] = '\0';
25301e196c8SJohn Marino     cur_name_add = nextpathptr = &nextpathbuf[MAXPATHLEN - 1];
25401e196c8SJohn Marino 
25501e196c8SJohn Marino     /* find the inode of the current directory */
25601e196c8SJohn Marino     if (lstat(".", &st_cur) == -1) {
25701e196c8SJohn Marino 	(void)sprintf(pathname,
25801e196c8SJohn Marino 			"getwd: Cannot stat \".\" (%s)", strerror(errno));
25901e196c8SJohn Marino 	return NULL;
26001e196c8SJohn Marino     }
26101e196c8SJohn Marino     nextpathptr = strrcpy(nextpathptr, "../");
26201e196c8SJohn Marino 
26301e196c8SJohn Marino     /* Descend to root */
26401e196c8SJohn Marino     for (;;) {
26501e196c8SJohn Marino 
26601e196c8SJohn Marino 	/* look if we found root yet */
26701e196c8SJohn Marino 	if (st_cur.st_ino == st_root.st_ino &&
26801e196c8SJohn Marino 	    DEV_DEV_COMPARE(st_cur.st_dev, st_root.st_dev)) {
26901e196c8SJohn Marino 	    (void)strcpy(pathname, *pathptr != '/' ? "/" : pathptr);
270ca58f742SDaniel Fojt 	    return pathname;
27101e196c8SJohn Marino 	}
27201e196c8SJohn Marino 
27301e196c8SJohn Marino 	/* open the parent directory */
27401e196c8SJohn Marino 	if (stat(nextpathptr, &st_dotdot) == -1) {
27501e196c8SJohn Marino 	    (void)sprintf(pathname,
27601e196c8SJohn Marino 			    "getwd: Cannot stat directory \"%s\" (%s)",
27701e196c8SJohn Marino 			    nextpathptr, strerror(errno));
27801e196c8SJohn Marino 	    return NULL;
27901e196c8SJohn Marino 	}
28001e196c8SJohn Marino 	if ((dp = opendir(nextpathptr)) == NULL) {
28101e196c8SJohn Marino 	    (void)sprintf(pathname,
28201e196c8SJohn Marino 			    "getwd: Cannot open directory \"%s\" (%s)",
28301e196c8SJohn Marino 			    nextpathptr, strerror(errno));
28401e196c8SJohn Marino 	    return NULL;
28501e196c8SJohn Marino 	}
28601e196c8SJohn Marino 
28701e196c8SJohn Marino 	/* look in the parent for the entry with the same inode */
28801e196c8SJohn Marino 	if (DEV_DEV_COMPARE(st_dotdot.st_dev, st_cur.st_dev)) {
28901e196c8SJohn Marino 	    /* Parent has same device. No need to stat every member */
29001e196c8SJohn Marino 	    for (d = readdir(dp); d != NULL; d = readdir(dp))
29101e196c8SJohn Marino 		if (d->d_fileno == st_cur.st_ino)
29201e196c8SJohn Marino 		    break;
293a34d5fb1SAntonio Huete Jimenez 	} else {
29401e196c8SJohn Marino 	    /*
29501e196c8SJohn Marino 	     * Parent has a different device. This is a mount point so we
29601e196c8SJohn Marino 	     * need to stat every member
29701e196c8SJohn Marino 	     */
29801e196c8SJohn Marino 	    for (d = readdir(dp); d != NULL; d = readdir(dp)) {
29901e196c8SJohn Marino 		if (ISDOT(d->d_name) || ISDOTDOT(d->d_name))
30001e196c8SJohn Marino 		    continue;
30101e196c8SJohn Marino 		(void)strcpy(cur_name_add, d->d_name);
30201e196c8SJohn Marino 		if (lstat(nextpathptr, &st_next) == -1) {
30301e196c8SJohn Marino 		    (void)sprintf(pathname,
30401e196c8SJohn Marino 			"getwd: Cannot stat \"%s\" (%s)",
30501e196c8SJohn Marino 			d->d_name, strerror(errno));
30601e196c8SJohn Marino 		    (void)closedir(dp);
30701e196c8SJohn Marino 		    return NULL;
30801e196c8SJohn Marino 		}
30901e196c8SJohn Marino 		/* check if we found it yet */
31001e196c8SJohn Marino 		if (st_next.st_ino == st_cur.st_ino &&
31101e196c8SJohn Marino 		    DEV_DEV_COMPARE(st_next.st_dev, st_cur.st_dev))
31201e196c8SJohn Marino 		    break;
31301e196c8SJohn Marino 	    }
31401e196c8SJohn Marino 	}
31501e196c8SJohn Marino 	if (d == NULL) {
31601e196c8SJohn Marino 	    (void)sprintf(pathname,
31701e196c8SJohn Marino 		"getwd: Cannot find \".\" in \"..\"");
31801e196c8SJohn Marino 	    (void)closedir(dp);
31901e196c8SJohn Marino 	    return NULL;
32001e196c8SJohn Marino 	}
32101e196c8SJohn Marino 	st_cur = st_dotdot;
32201e196c8SJohn Marino 	pathptr = strrcpy(pathptr, d->d_name);
32301e196c8SJohn Marino 	pathptr = strrcpy(pathptr, "/");
32401e196c8SJohn Marino 	nextpathptr = strrcpy(nextpathptr, "../");
32501e196c8SJohn Marino 	(void)closedir(dp);
32601e196c8SJohn Marino 	*cur_name_add = '\0';
32701e196c8SJohn Marino     }
32801e196c8SJohn Marino } /* end getwd */
32901e196c8SJohn Marino 
33001e196c8SJohn Marino #endif /* __hpux */
33101e196c8SJohn Marino 
33201e196c8SJohn Marino #if !defined(HAVE_GETCWD)
33301e196c8SJohn Marino char *
getcwd(path,sz)33401e196c8SJohn Marino getcwd(path, sz)
33501e196c8SJohn Marino      char *path;
33601e196c8SJohn Marino      int sz;
33701e196c8SJohn Marino {
33801e196c8SJohn Marino 	return getwd(path);
33901e196c8SJohn Marino }
34001e196c8SJohn Marino #endif
34101e196c8SJohn Marino 
342*6eef5f0cSAntonio Huete Jimenez #if !defined(HAVE_SIGACTION)
343*6eef5f0cSAntonio Huete Jimenez #include "sigact.h"
344*6eef5f0cSAntonio Huete Jimenez #endif
345*6eef5f0cSAntonio Huete Jimenez 
34601e196c8SJohn Marino /* force posix signals */
347a34d5fb1SAntonio Huete Jimenez SignalProc
bmake_signal(int s,SignalProc a)348a34d5fb1SAntonio Huete Jimenez bmake_signal(int s, SignalProc a)
34901e196c8SJohn Marino {
35001e196c8SJohn Marino 	struct sigaction sa, osa;
35101e196c8SJohn Marino 
35201e196c8SJohn Marino 	sa.sa_handler = a;
35301e196c8SJohn Marino 	sigemptyset(&sa.sa_mask);
35401e196c8SJohn Marino 	sa.sa_flags = SA_RESTART;
35501e196c8SJohn Marino 
35601e196c8SJohn Marino 	if (sigaction(s, &sa, &osa) == -1)
35701e196c8SJohn Marino 		return SIG_ERR;
35801e196c8SJohn Marino 	else
35901e196c8SJohn Marino 		return osa.sa_handler;
36001e196c8SJohn Marino }
36101e196c8SJohn Marino 
36201e196c8SJohn Marino #if !defined(HAVE_VSNPRINTF) || !defined(HAVE_VASPRINTF)
36301e196c8SJohn Marino #include <stdarg.h>
36401e196c8SJohn Marino #endif
36501e196c8SJohn Marino 
36601e196c8SJohn Marino #if !defined(HAVE_VSNPRINTF)
36701e196c8SJohn Marino #if !defined(__osf__)
36801e196c8SJohn Marino #ifdef _IOSTRG
36901e196c8SJohn Marino #define STRFLAG	(_IOSTRG|_IOWRT)	/* no _IOWRT: avoid stdio bug */
37001e196c8SJohn Marino #else
37101e196c8SJohn Marino #if 0
37201e196c8SJohn Marino #define STRFLAG	(_IOREAD)		/* XXX: Assume svr4 stdio */
37301e196c8SJohn Marino #endif
37401e196c8SJohn Marino #endif /* _IOSTRG */
37501e196c8SJohn Marino #endif /* __osf__ */
37601e196c8SJohn Marino 
37701e196c8SJohn Marino int
vsnprintf(char * s,size_t n,const char * fmt,va_list args)37801e196c8SJohn Marino vsnprintf(char *s, size_t n, const char *fmt, va_list args)
37901e196c8SJohn Marino {
38001e196c8SJohn Marino #ifdef STRFLAG
38101e196c8SJohn Marino 	FILE fakebuf;
38201e196c8SJohn Marino 
38301e196c8SJohn Marino 	fakebuf._flag = STRFLAG;
38401e196c8SJohn Marino 	/*
38501e196c8SJohn Marino 	 * Some os's are char * _ptr, others are unsigned char *_ptr...
38601e196c8SJohn Marino 	 * We cast to void * to make everyone happy.
38701e196c8SJohn Marino 	 */
38801e196c8SJohn Marino 	fakebuf._ptr = (void *)s;
38901e196c8SJohn Marino 	fakebuf._cnt = n - 1;
39001e196c8SJohn Marino 	fakebuf._file = -1;
39101e196c8SJohn Marino 	_doprnt(fmt, args, &fakebuf);
39201e196c8SJohn Marino 	fakebuf._cnt++;
39301e196c8SJohn Marino 	putc('\0', &fakebuf);
39401e196c8SJohn Marino 	if (fakebuf._cnt < 0)
39501e196c8SJohn Marino 		fakebuf._cnt = 0;
396ca58f742SDaniel Fojt 	return n - fakebuf._cnt - 1;
39701e196c8SJohn Marino #else
39801e196c8SJohn Marino #ifndef _PATH_DEVNULL
39901e196c8SJohn Marino # define _PATH_DEVNULL "/dev/null"
40001e196c8SJohn Marino #endif
40101e196c8SJohn Marino 	/*
40201e196c8SJohn Marino 	 * Rats... we don't want to clobber anything...
40301e196c8SJohn Marino 	 * do a printf to /dev/null to see how much space we need.
40401e196c8SJohn Marino 	 */
40501e196c8SJohn Marino 	static FILE *nullfp;
40601e196c8SJohn Marino 	int need = 0;			/* XXX what's a useful error return? */
40701e196c8SJohn Marino 
40801e196c8SJohn Marino 	if (!nullfp)
40901e196c8SJohn Marino 		nullfp = fopen(_PATH_DEVNULL, "w");
41001e196c8SJohn Marino 	if (nullfp) {
41101e196c8SJohn Marino 		need = vfprintf(nullfp, fmt, args);
41201e196c8SJohn Marino 		if (need < n)
41301e196c8SJohn Marino 			(void)vsprintf(s, fmt, args);
41401e196c8SJohn Marino 	}
41501e196c8SJohn Marino 	return need;
41601e196c8SJohn Marino #endif
41701e196c8SJohn Marino }
41801e196c8SJohn Marino #endif
41901e196c8SJohn Marino 
42001e196c8SJohn Marino #if !defined(HAVE_SNPRINTF)
42101e196c8SJohn Marino int
snprintf(char * s,size_t n,const char * fmt,...)42201e196c8SJohn Marino snprintf(char *s, size_t n, const char *fmt, ...)
42301e196c8SJohn Marino {
42401e196c8SJohn Marino 	va_list ap;
42501e196c8SJohn Marino 	int rv;
42601e196c8SJohn Marino 
42701e196c8SJohn Marino 	va_start(ap, fmt);
42801e196c8SJohn Marino 	rv = vsnprintf(s, n, fmt, ap);
42901e196c8SJohn Marino 	va_end(ap);
43001e196c8SJohn Marino 	return rv;
43101e196c8SJohn Marino }
43201e196c8SJohn Marino #endif
43301e196c8SJohn Marino 
43401e196c8SJohn Marino #if !defined(HAVE_STRFTIME)
43501e196c8SJohn Marino size_t
strftime(char * buf,size_t len,const char * fmt,const struct tm * tm)43601e196c8SJohn Marino strftime(char *buf, size_t len, const char *fmt, const struct tm *tm)
43701e196c8SJohn Marino {
43801e196c8SJohn Marino 	static char months[][4] = {
43901e196c8SJohn Marino 		"Jan", "Feb", "Mar", "Apr", "May", "Jun",
44001e196c8SJohn Marino 		"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
44101e196c8SJohn Marino 	};
44201e196c8SJohn Marino 
44301e196c8SJohn Marino 	size_t s;
44401e196c8SJohn Marino 	char *b = buf;
44501e196c8SJohn Marino 
44601e196c8SJohn Marino 	while (*fmt) {
44701e196c8SJohn Marino 		if (len == 0)
44801e196c8SJohn Marino 			return buf - b;
44901e196c8SJohn Marino 		if (*fmt != '%') {
45001e196c8SJohn Marino 			*buf++ = *fmt++;
45101e196c8SJohn Marino 			len--;
45201e196c8SJohn Marino 			continue;
45301e196c8SJohn Marino 		}
45401e196c8SJohn Marino 		switch (*fmt++) {
45501e196c8SJohn Marino 		case '%':
45601e196c8SJohn Marino 			*buf++ = '%';
45701e196c8SJohn Marino 			len--;
45801e196c8SJohn Marino 			if (len == 0) return buf - b;
45901e196c8SJohn Marino 			/*FALLTHROUGH*/
46001e196c8SJohn Marino 		case '\0':
46101e196c8SJohn Marino 			*buf = '%';
46201e196c8SJohn Marino 			s = 1;
46301e196c8SJohn Marino 			break;
46401e196c8SJohn Marino 		case 'k':
46501e196c8SJohn Marino 			s = snprintf(buf, len, "%d", tm->tm_hour);
46601e196c8SJohn Marino 			break;
46701e196c8SJohn Marino 		case 'M':
46801e196c8SJohn Marino 			s = snprintf(buf, len, "%02d", tm->tm_min);
46901e196c8SJohn Marino 			break;
47001e196c8SJohn Marino 		case 'S':
47101e196c8SJohn Marino 			s = snprintf(buf, len, "%02d", tm->tm_sec);
47201e196c8SJohn Marino 			break;
47301e196c8SJohn Marino 		case 'b':
47401e196c8SJohn Marino 			if (tm->tm_mon >= 12)
47501e196c8SJohn Marino 				return buf - b;
47601e196c8SJohn Marino 			s = snprintf(buf, len, "%s", months[tm->tm_mon]);
47701e196c8SJohn Marino 			break;
47801e196c8SJohn Marino 		case 'd':
47901e196c8SJohn Marino 			s = snprintf(buf, len, "%02d", tm->tm_mday);
48001e196c8SJohn Marino 			break;
48101e196c8SJohn Marino 		case 'Y':
48201e196c8SJohn Marino 			s = snprintf(buf, len, "%d", 1900 + tm->tm_year);
48301e196c8SJohn Marino 			break;
48401e196c8SJohn Marino 		default:
48501e196c8SJohn Marino 			s = snprintf(buf, len, "Unsupported format %c",
48601e196c8SJohn Marino 			    fmt[-1]);
48701e196c8SJohn Marino 			break;
48801e196c8SJohn Marino 		}
48901e196c8SJohn Marino 		buf += s;
49001e196c8SJohn Marino 		len -= s;
49101e196c8SJohn Marino 	}
492a34d5fb1SAntonio Huete Jimenez 	return buf - b;
49301e196c8SJohn Marino }
49401e196c8SJohn Marino #endif
49501e196c8SJohn Marino 
49601e196c8SJohn Marino #if !defined(HAVE_KILLPG)
49701e196c8SJohn Marino #if !defined(__hpux__) && !defined(__hpux)
49801e196c8SJohn Marino int
killpg(int pid,int sig)49901e196c8SJohn Marino killpg(int pid, int sig)
50001e196c8SJohn Marino {
50101e196c8SJohn Marino     return kill(-pid, sig);
50201e196c8SJohn Marino }
50301e196c8SJohn Marino #endif
50401e196c8SJohn Marino #endif
50501e196c8SJohn Marino 
50601e196c8SJohn Marino #if !defined(HAVE_WARNX)
50701e196c8SJohn Marino static void
vwarnx(const char * fmt,va_list args)50801e196c8SJohn Marino vwarnx(const char *fmt, va_list args)
50901e196c8SJohn Marino {
51001e196c8SJohn Marino 	fprintf(stderr, "%s: ", progname);
51101e196c8SJohn Marino 	if ((fmt)) {
51201e196c8SJohn Marino 		vfprintf(stderr, fmt, args);
51301e196c8SJohn Marino 		fprintf(stderr, ": ");
51401e196c8SJohn Marino 	}
51501e196c8SJohn Marino }
51601e196c8SJohn Marino #endif
51701e196c8SJohn Marino 
51801e196c8SJohn Marino #if !defined(HAVE_WARN)
51901e196c8SJohn Marino static void
vwarn(const char * fmt,va_list args)52001e196c8SJohn Marino vwarn(const char *fmt, va_list args)
52101e196c8SJohn Marino {
52201e196c8SJohn Marino 	vwarnx(fmt, args);
52301e196c8SJohn Marino 	fprintf(stderr, "%s\n", strerror(errno));
52401e196c8SJohn Marino }
52501e196c8SJohn Marino #endif
52601e196c8SJohn Marino 
52701e196c8SJohn Marino #if !defined(HAVE_ERR)
52801e196c8SJohn Marino static void
verr(int eval,const char * fmt,va_list args)52901e196c8SJohn Marino verr(int eval, const char *fmt, va_list args)
53001e196c8SJohn Marino {
53101e196c8SJohn Marino 	vwarn(fmt, args);
53201e196c8SJohn Marino 	exit(eval);
53301e196c8SJohn Marino }
53401e196c8SJohn Marino #endif
53501e196c8SJohn Marino 
53601e196c8SJohn Marino #if !defined(HAVE_ERRX)
53701e196c8SJohn Marino static void
verrx(int eval,const char * fmt,va_list args)53801e196c8SJohn Marino verrx(int eval, const char *fmt, va_list args)
53901e196c8SJohn Marino {
54001e196c8SJohn Marino 	vwarnx(fmt, args);
54101e196c8SJohn Marino 	exit(eval);
54201e196c8SJohn Marino }
54301e196c8SJohn Marino #endif
54401e196c8SJohn Marino 
54501e196c8SJohn Marino #if !defined(HAVE_ERR)
54601e196c8SJohn Marino void
err(int eval,const char * fmt,...)54701e196c8SJohn Marino err(int eval, const char *fmt, ...)
54801e196c8SJohn Marino {
54901e196c8SJohn Marino         va_list ap;
55001e196c8SJohn Marino 
55101e196c8SJohn Marino         va_start(ap, fmt);
55201e196c8SJohn Marino         verr(eval, fmt, ap);
55301e196c8SJohn Marino         va_end(ap);
55401e196c8SJohn Marino }
55501e196c8SJohn Marino #endif
55601e196c8SJohn Marino 
55701e196c8SJohn Marino #if !defined(HAVE_ERRX)
55801e196c8SJohn Marino void
errx(int eval,const char * fmt,...)55901e196c8SJohn Marino errx(int eval, const char *fmt, ...)
56001e196c8SJohn Marino {
56101e196c8SJohn Marino         va_list ap;
56201e196c8SJohn Marino 
56301e196c8SJohn Marino         va_start(ap, fmt);
56401e196c8SJohn Marino         verrx(eval, fmt, ap);
56501e196c8SJohn Marino         va_end(ap);
56601e196c8SJohn Marino }
56701e196c8SJohn Marino #endif
56801e196c8SJohn Marino 
56901e196c8SJohn Marino #if !defined(HAVE_WARN)
57001e196c8SJohn Marino void
warn(const char * fmt,...)57101e196c8SJohn Marino warn(const char *fmt, ...)
57201e196c8SJohn Marino {
57301e196c8SJohn Marino         va_list ap;
57401e196c8SJohn Marino 
57501e196c8SJohn Marino         va_start(ap, fmt);
57601e196c8SJohn Marino         vwarn(fmt, ap);
57701e196c8SJohn Marino         va_end(ap);
57801e196c8SJohn Marino }
57901e196c8SJohn Marino #endif
58001e196c8SJohn Marino 
58101e196c8SJohn Marino #if !defined(HAVE_WARNX)
58201e196c8SJohn Marino void
warnx(const char * fmt,...)58301e196c8SJohn Marino warnx(const char *fmt, ...)
58401e196c8SJohn Marino {
58501e196c8SJohn Marino         va_list ap;
58601e196c8SJohn Marino 
58701e196c8SJohn Marino         va_start(ap, fmt);
58801e196c8SJohn Marino         vwarnx(fmt, ap);
58901e196c8SJohn Marino         va_end(ap);
59001e196c8SJohn Marino }
59101e196c8SJohn Marino #endif
592*6eef5f0cSAntonio Huete Jimenez 
593*6eef5f0cSAntonio Huete Jimenez #ifdef HAVE_INTTYPES_H
594*6eef5f0cSAntonio Huete Jimenez #include <inttypes.h>
595*6eef5f0cSAntonio Huete Jimenez #elif defined(HAVE_STDINT_H)
596*6eef5f0cSAntonio Huete Jimenez #include <stdint.h>
597*6eef5f0cSAntonio Huete Jimenez #endif
598*6eef5f0cSAntonio Huete Jimenez #ifdef HAVE_LIMITS_H
599*6eef5f0cSAntonio Huete Jimenez #include <limits.h>
600*6eef5f0cSAntonio Huete Jimenez #endif
601*6eef5f0cSAntonio Huete Jimenez 
602*6eef5f0cSAntonio Huete Jimenez #ifndef NUM_TYPE
603*6eef5f0cSAntonio Huete Jimenez # ifdef HAVE_LONG_LONG_INT
604*6eef5f0cSAntonio Huete Jimenez #   define NUM_TYPE long long
605*6eef5f0cSAntonio Huete Jimenez # elif defined(_INT64_T_DECLARED) || defined(int64_t)
606*6eef5f0cSAntonio Huete Jimenez #   define NUM_TYPE int64_t
607*6eef5f0cSAntonio Huete Jimenez # endif
608*6eef5f0cSAntonio Huete Jimenez #endif
609*6eef5f0cSAntonio Huete Jimenez 
610*6eef5f0cSAntonio Huete Jimenez #ifdef NUM_TYPE
611*6eef5f0cSAntonio Huete Jimenez #if !defined(HAVE_STRTOLL)
612*6eef5f0cSAntonio Huete Jimenez #define BCS_ONLY
613*6eef5f0cSAntonio Huete Jimenez #define _FUNCNAME strtoll
614*6eef5f0cSAntonio Huete Jimenez #define __INT NUM_TYPE
615*6eef5f0cSAntonio Huete Jimenez #undef __INT_MIN
616*6eef5f0cSAntonio Huete Jimenez #undef __INT_MAX
617*6eef5f0cSAntonio Huete Jimenez #ifdef LLONG_MAX
618*6eef5f0cSAntonio Huete Jimenez # define __INT_MIN LLONG_MIN
619*6eef5f0cSAntonio Huete Jimenez # define __INT_MAX LLONG_MAX
620*6eef5f0cSAntonio Huete Jimenez #elif defined(INT64_MAX)
621*6eef5f0cSAntonio Huete Jimenez # define __INT_MIN INT64_MIN
622*6eef5f0cSAntonio Huete Jimenez # define __INT_MAX INT64_MAX
623*6eef5f0cSAntonio Huete Jimenez #endif
624*6eef5f0cSAntonio Huete Jimenez #ifndef _DIAGASSERT
625*6eef5f0cSAntonio Huete Jimenez # define _DIAGASSERT(e)
626*6eef5f0cSAntonio Huete Jimenez #endif
627*6eef5f0cSAntonio Huete Jimenez #ifndef __UNCONST
628*6eef5f0cSAntonio Huete Jimenez # define __UNCONST(a)      ((void *)(unsigned long)(const void *)(a))
629*6eef5f0cSAntonio Huete Jimenez #endif
630*6eef5f0cSAntonio Huete Jimenez #include "_strtol.h"
631*6eef5f0cSAntonio Huete Jimenez #endif
632*6eef5f0cSAntonio Huete Jimenez 
633*6eef5f0cSAntonio Huete Jimenez #endif
634*6eef5f0cSAntonio Huete Jimenez 
635*6eef5f0cSAntonio Huete Jimenez #if !defined(HAVE_STRTOL)
636*6eef5f0cSAntonio Huete Jimenez #define BCS_ONLY
637*6eef5f0cSAntonio Huete Jimenez #define _FUNCNAME strtol
638*6eef5f0cSAntonio Huete Jimenez #define __INT long
639*6eef5f0cSAntonio Huete Jimenez #undef __INT_MIN
640*6eef5f0cSAntonio Huete Jimenez #undef __INT_MAX
641*6eef5f0cSAntonio Huete Jimenez #define __INT_MIN LONG_MIN
642*6eef5f0cSAntonio Huete Jimenez #define __INT_MAX LONG_MAX
643*6eef5f0cSAntonio Huete Jimenez #ifndef _DIAGASSERT
644*6eef5f0cSAntonio Huete Jimenez # define _DIAGASSERT(e)
645*6eef5f0cSAntonio Huete Jimenez #endif
646*6eef5f0cSAntonio Huete Jimenez #ifndef __UNCONST
647*6eef5f0cSAntonio Huete Jimenez # define __UNCONST(a)      ((void *)(unsigned long)(const void *)(a))
648*6eef5f0cSAntonio Huete Jimenez #endif
649*6eef5f0cSAntonio Huete Jimenez #include "_strtol.h"
650*6eef5f0cSAntonio Huete Jimenez #endif
651*6eef5f0cSAntonio Huete Jimenez 
652*6eef5f0cSAntonio Huete Jimenez #if !defined(HAVE_STRTOUL)
653*6eef5f0cSAntonio Huete Jimenez #define BCS_ONLY
654*6eef5f0cSAntonio Huete Jimenez #define _FUNCNAME strtoul
655*6eef5f0cSAntonio Huete Jimenez #define __INT unsigned long
656*6eef5f0cSAntonio Huete Jimenez #undef __INT_MIN
657*6eef5f0cSAntonio Huete Jimenez #undef __INT_MAX
658*6eef5f0cSAntonio Huete Jimenez #define __INT_MIN 0
659*6eef5f0cSAntonio Huete Jimenez #define __INT_MAX ULONG_MAX
660*6eef5f0cSAntonio Huete Jimenez #ifndef _DIAGASSERT
661*6eef5f0cSAntonio Huete Jimenez # define _DIAGASSERT(e)
662*6eef5f0cSAntonio Huete Jimenez #endif
663*6eef5f0cSAntonio Huete Jimenez #ifndef __UNCONST
664*6eef5f0cSAntonio Huete Jimenez # define __UNCONST(a)      ((void *)(unsigned long)(const void *)(a))
665*6eef5f0cSAntonio Huete Jimenez #endif
666*6eef5f0cSAntonio Huete Jimenez #include "_strtol.h"
667*6eef5f0cSAntonio Huete Jimenez #endif
668