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