19f45a3c8SSimon J. Gerraty /* $NetBSD: util.c,v 1.78 2021/12/15 12:58:01 rillig Exp $ */ 23955d011SMarcel Moolenaar 33955d011SMarcel Moolenaar /* 43955d011SMarcel Moolenaar * Missing stuff from OS's 53955d011SMarcel Moolenaar * 6*d5e0a182SSimon J. Gerraty * $Id: util.c,v 1.52 2024/01/04 00:27:30 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 169f45a3c8SSimon J. Gerraty MAKE_RCSID("$NetBSD: util.c,v 1.78 2021/12/15 12:58:01 rillig Exp $"); 17956e45f6SSimon J. Gerraty 18956e45f6SSimon J. Gerraty #if !defined(MAKE_NATIVE) && !defined(HAVE_STRERROR) 193955d011SMarcel Moolenaar extern int errno, sys_nerr; 203955d011SMarcel Moolenaar extern char *sys_errlist[]; 213955d011SMarcel Moolenaar 223955d011SMarcel Moolenaar char * 233955d011SMarcel Moolenaar strerror(int e) 243955d011SMarcel Moolenaar { 253955d011SMarcel Moolenaar static char buf[100]; 263955d011SMarcel Moolenaar if (e < 0 || e >= sys_nerr) { 27e2eeea75SSimon J. Gerraty snprintf(buf, sizeof buf, "Unknown error %d", e); 283955d011SMarcel Moolenaar return buf; 29e2eeea75SSimon J. Gerraty } else 303955d011SMarcel Moolenaar return sys_errlist[e]; 313955d011SMarcel Moolenaar } 323955d011SMarcel Moolenaar #endif 333955d011SMarcel Moolenaar 343955d011SMarcel Moolenaar #if !defined(HAVE_GETENV) || !defined(HAVE_SETENV) || !defined(HAVE_UNSETENV) 353955d011SMarcel Moolenaar extern char **environ; 363955d011SMarcel Moolenaar 373955d011SMarcel Moolenaar static char * 383955d011SMarcel Moolenaar findenv(const char *name, int *offset) 393955d011SMarcel Moolenaar { 403955d011SMarcel Moolenaar size_t i, len; 413955d011SMarcel Moolenaar char *p, *q; 423955d011SMarcel Moolenaar 433955d011SMarcel Moolenaar len = strlen(name); 443955d011SMarcel Moolenaar for (i = 0; (q = environ[i]); i++) { 453955d011SMarcel Moolenaar p = strchr(q, '='); 463955d011SMarcel Moolenaar if (p == NULL || p - q != len) 473955d011SMarcel Moolenaar continue; 483955d011SMarcel Moolenaar if (strncmp(name, q, len) == 0) { 493955d011SMarcel Moolenaar *offset = i; 503955d011SMarcel Moolenaar return q + len + 1; 513955d011SMarcel Moolenaar } 523955d011SMarcel Moolenaar } 533955d011SMarcel Moolenaar *offset = i; 543955d011SMarcel Moolenaar return NULL; 553955d011SMarcel Moolenaar } 563955d011SMarcel Moolenaar 573955d011SMarcel Moolenaar char * 583955d011SMarcel Moolenaar getenv(const char *name) 593955d011SMarcel Moolenaar { 603955d011SMarcel Moolenaar int offset; 613955d011SMarcel Moolenaar 623841c287SSimon J. Gerraty return findenv(name, &offset); 633955d011SMarcel Moolenaar } 643955d011SMarcel Moolenaar 653955d011SMarcel Moolenaar int 663955d011SMarcel Moolenaar unsetenv(const char *name) 673955d011SMarcel Moolenaar { 683955d011SMarcel Moolenaar char **p; 693955d011SMarcel Moolenaar int offset; 703955d011SMarcel Moolenaar 713955d011SMarcel Moolenaar if (name == NULL || *name == '\0' || strchr(name, '=') != NULL) { 723955d011SMarcel Moolenaar errno = EINVAL; 733955d011SMarcel Moolenaar return -1; 743955d011SMarcel Moolenaar } 753955d011SMarcel Moolenaar 763955d011SMarcel Moolenaar while (findenv(name, &offset)) { /* if set multiple times */ 77dba7b0efSSimon J. Gerraty for (p = &environ[offset];; p++) 783955d011SMarcel Moolenaar if (!(*p = *(p + 1))) 793955d011SMarcel Moolenaar break; 803955d011SMarcel Moolenaar } 813955d011SMarcel Moolenaar return 0; 823955d011SMarcel Moolenaar } 833955d011SMarcel Moolenaar 843955d011SMarcel Moolenaar int 853955d011SMarcel Moolenaar setenv(const char *name, const char *value, int rewrite) 863955d011SMarcel Moolenaar { 873955d011SMarcel Moolenaar char *c, **newenv; 883955d011SMarcel Moolenaar const char *cc; 893955d011SMarcel Moolenaar size_t l_value, size; 903955d011SMarcel Moolenaar int offset; 913955d011SMarcel Moolenaar 923955d011SMarcel Moolenaar if (name == NULL || value == NULL) { 933955d011SMarcel Moolenaar errno = EINVAL; 943955d011SMarcel Moolenaar return -1; 953955d011SMarcel Moolenaar } 963955d011SMarcel Moolenaar 973955d011SMarcel Moolenaar if (*value == '=') /* no `=' in value */ 98e2eeea75SSimon J. Gerraty value++; 993955d011SMarcel Moolenaar l_value = strlen(value); 1003955d011SMarcel Moolenaar 1013955d011SMarcel Moolenaar /* find if already exists */ 1023955d011SMarcel Moolenaar if ((c = findenv(name, &offset))) { 1033955d011SMarcel Moolenaar if (!rewrite) 1043955d011SMarcel Moolenaar return 0; 1053955d011SMarcel Moolenaar if (strlen(c) >= l_value) /* old larger; copy over */ 1063955d011SMarcel Moolenaar goto copy; 1073955d011SMarcel Moolenaar } else { /* create new slot */ 1083955d011SMarcel Moolenaar size = sizeof(char *) * (offset + 2); 1093955d011SMarcel Moolenaar if (savedEnv == environ) { /* just increase size */ 1103955d011SMarcel Moolenaar if ((newenv = realloc(savedEnv, size)) == NULL) 1113955d011SMarcel Moolenaar return -1; 1123955d011SMarcel Moolenaar savedEnv = newenv; 1133955d011SMarcel Moolenaar } else { /* get new space */ 1143955d011SMarcel Moolenaar /* 1153955d011SMarcel Moolenaar * We don't free here because we don't know if 1163955d011SMarcel Moolenaar * the first allocation is valid on all OS's 1173955d011SMarcel Moolenaar */ 1183955d011SMarcel Moolenaar if ((savedEnv = malloc(size)) == NULL) 1193955d011SMarcel Moolenaar return -1; 1203955d011SMarcel Moolenaar (void)memcpy(savedEnv, environ, size - sizeof(char *)); 1213955d011SMarcel Moolenaar } 1223955d011SMarcel Moolenaar environ = savedEnv; 1233955d011SMarcel Moolenaar environ[offset + 1] = NULL; 1243955d011SMarcel Moolenaar } 125dba7b0efSSimon J. Gerraty for (cc = name; *cc && *cc != '='; cc++) /* no `=' in name */ 1263955d011SMarcel Moolenaar continue; 1273955d011SMarcel Moolenaar size = cc - name; 1283955d011SMarcel Moolenaar /* name + `=' + value */ 1293955d011SMarcel Moolenaar if ((environ[offset] = malloc(size + l_value + 2)) == NULL) 1303955d011SMarcel Moolenaar return -1; 1313955d011SMarcel Moolenaar c = environ[offset]; 1323955d011SMarcel Moolenaar (void)memcpy(c, name, size); 1333955d011SMarcel Moolenaar c += size; 1343955d011SMarcel Moolenaar *c++ = '='; 1353955d011SMarcel Moolenaar copy: 1363955d011SMarcel Moolenaar (void)memcpy(c, value, l_value + 1); 1373955d011SMarcel Moolenaar return 0; 1383955d011SMarcel Moolenaar } 1393955d011SMarcel Moolenaar 1403955d011SMarcel Moolenaar #ifdef TEST 1413955d011SMarcel Moolenaar int 1423955d011SMarcel Moolenaar main(int argc, char *argv[]) 1433955d011SMarcel Moolenaar { 1443955d011SMarcel Moolenaar setenv(argv[1], argv[2], 0); 1453955d011SMarcel Moolenaar printf("%s\n", getenv(argv[1])); 1463955d011SMarcel Moolenaar unsetenv(argv[1]); 1473955d011SMarcel Moolenaar printf("%s\n", getenv(argv[1])); 1483955d011SMarcel Moolenaar return 0; 1493955d011SMarcel Moolenaar } 1503955d011SMarcel Moolenaar #endif 1513955d011SMarcel Moolenaar 1523955d011SMarcel Moolenaar #endif 1533955d011SMarcel Moolenaar 1543955d011SMarcel Moolenaar 1553955d011SMarcel Moolenaar #if defined(__hpux__) || defined(__hpux) 15606b9b3e0SSimon J. Gerraty /* 15706b9b3e0SSimon J. Gerraty * strrcpy(): 1583955d011SMarcel Moolenaar * Like strcpy, going backwards and returning the new pointer 1593955d011SMarcel Moolenaar */ 1603955d011SMarcel Moolenaar static char * 1613955d011SMarcel Moolenaar strrcpy(char *ptr, char *str) 1623955d011SMarcel Moolenaar { 1633955d011SMarcel Moolenaar int len = strlen(str); 1643955d011SMarcel Moolenaar 16506b9b3e0SSimon J. Gerraty while (len != 0) 1663955d011SMarcel Moolenaar *--ptr = str[--len]; 1673955d011SMarcel Moolenaar 1683841c287SSimon J. Gerraty return ptr; 1699f45a3c8SSimon J. Gerraty } 1703955d011SMarcel Moolenaar 1713955d011SMarcel Moolenaar char *sys_siglist[] = { 1723955d011SMarcel Moolenaar "Signal 0", 1733955d011SMarcel Moolenaar "Hangup", /* SIGHUP */ 1743955d011SMarcel Moolenaar "Interrupt", /* SIGINT */ 1753955d011SMarcel Moolenaar "Quit", /* SIGQUIT */ 1763955d011SMarcel Moolenaar "Illegal instruction", /* SIGILL */ 1773955d011SMarcel Moolenaar "Trace/BPT trap", /* SIGTRAP */ 1783955d011SMarcel Moolenaar "IOT trap", /* SIGIOT */ 1793955d011SMarcel Moolenaar "EMT trap", /* SIGEMT */ 1803955d011SMarcel Moolenaar "Floating point exception", /* SIGFPE */ 1813955d011SMarcel Moolenaar "Killed", /* SIGKILL */ 1823955d011SMarcel Moolenaar "Bus error", /* SIGBUS */ 1833955d011SMarcel Moolenaar "Segmentation fault", /* SIGSEGV */ 1843955d011SMarcel Moolenaar "Bad system call", /* SIGSYS */ 1853955d011SMarcel Moolenaar "Broken pipe", /* SIGPIPE */ 1863955d011SMarcel Moolenaar "Alarm clock", /* SIGALRM */ 1873955d011SMarcel Moolenaar "Terminated", /* SIGTERM */ 1883955d011SMarcel Moolenaar "User defined signal 1", /* SIGUSR1 */ 1893955d011SMarcel Moolenaar "User defined signal 2", /* SIGUSR2 */ 1903955d011SMarcel Moolenaar "Child exited", /* SIGCLD */ 1913955d011SMarcel Moolenaar "Power-fail restart", /* SIGPWR */ 1923955d011SMarcel Moolenaar "Virtual timer expired", /* SIGVTALRM */ 1933955d011SMarcel Moolenaar "Profiling timer expired", /* SIGPROF */ 1943955d011SMarcel Moolenaar "I/O possible", /* SIGIO */ 1953955d011SMarcel Moolenaar "Window size changes", /* SIGWINDOW */ 1963955d011SMarcel Moolenaar "Stopped (signal)", /* SIGSTOP */ 1973955d011SMarcel Moolenaar "Stopped", /* SIGTSTP */ 1983955d011SMarcel Moolenaar "Continued", /* SIGCONT */ 1993955d011SMarcel Moolenaar "Stopped (tty input)", /* SIGTTIN */ 2003955d011SMarcel Moolenaar "Stopped (tty output)", /* SIGTTOU */ 2013955d011SMarcel Moolenaar "Urgent I/O condition", /* SIGURG */ 2023955d011SMarcel Moolenaar "Remote lock lost (NFS)", /* SIGLOST */ 2033955d011SMarcel Moolenaar "Signal 31", /* reserved */ 2043955d011SMarcel Moolenaar "DIL signal" /* SIGDIL */ 2053955d011SMarcel Moolenaar }; 2063955d011SMarcel Moolenaar #endif /* __hpux__ || __hpux */ 2073955d011SMarcel Moolenaar 2083955d011SMarcel Moolenaar #if defined(__hpux__) || defined(__hpux) 2093955d011SMarcel Moolenaar #include <sys/types.h> 2103955d011SMarcel Moolenaar #include <sys/syscall.h> 2113955d011SMarcel Moolenaar #include <sys/signal.h> 2123955d011SMarcel Moolenaar #include <sys/stat.h> 2133955d011SMarcel Moolenaar #include <dirent.h> 2143955d011SMarcel Moolenaar #include <sys/time.h> 2153955d011SMarcel Moolenaar #include <unistd.h> 2163955d011SMarcel Moolenaar 2173955d011SMarcel Moolenaar int 2183955d011SMarcel Moolenaar killpg(int pid, int sig) 2193955d011SMarcel Moolenaar { 2203955d011SMarcel Moolenaar return kill(-pid, sig); 2213955d011SMarcel Moolenaar } 2223955d011SMarcel Moolenaar 2233955d011SMarcel Moolenaar #if !defined(BSD) && !defined(d_fileno) 2243955d011SMarcel Moolenaar # define d_fileno d_ino 2253955d011SMarcel Moolenaar #endif 2263955d011SMarcel Moolenaar 2273955d011SMarcel Moolenaar #ifndef DEV_DEV_COMPARE 2283955d011SMarcel Moolenaar # define DEV_DEV_COMPARE(a, b) ((a) == (b)) 2293955d011SMarcel Moolenaar #endif 2303955d011SMarcel Moolenaar #define ISDOT(c) ((c)[0] == '.' && (((c)[1] == '\0') || ((c)[1] == '/'))) 2313955d011SMarcel Moolenaar #define ISDOTDOT(c) ((c)[0] == '.' && ISDOT(&((c)[1]))) 2323955d011SMarcel Moolenaar 2333955d011SMarcel Moolenaar char * 2343955d011SMarcel Moolenaar getwd(char *pathname) 2353955d011SMarcel Moolenaar { 2363955d011SMarcel Moolenaar DIR *dp; 2373955d011SMarcel Moolenaar struct dirent *d; 2383955d011SMarcel Moolenaar extern int errno; 2393955d011SMarcel Moolenaar 2403955d011SMarcel Moolenaar struct stat st_root, st_cur, st_next, st_dotdot; 2413955d011SMarcel Moolenaar char pathbuf[MAXPATHLEN], nextpathbuf[MAXPATHLEN * 2]; 2423955d011SMarcel Moolenaar char *pathptr, *nextpathptr, *cur_name_add; 2433955d011SMarcel Moolenaar 2443955d011SMarcel Moolenaar /* find the inode of root */ 2453955d011SMarcel Moolenaar if (stat("/", &st_root) == -1) { 2463955d011SMarcel Moolenaar (void)sprintf(pathname, 2473955d011SMarcel Moolenaar "getwd: Cannot stat \"/\" (%s)", strerror(errno)); 2483955d011SMarcel Moolenaar return NULL; 2493955d011SMarcel Moolenaar } 2503955d011SMarcel Moolenaar pathbuf[MAXPATHLEN - 1] = '\0'; 2513955d011SMarcel Moolenaar pathptr = &pathbuf[MAXPATHLEN - 1]; 2523955d011SMarcel Moolenaar nextpathbuf[MAXPATHLEN - 1] = '\0'; 2533955d011SMarcel Moolenaar cur_name_add = nextpathptr = &nextpathbuf[MAXPATHLEN - 1]; 2543955d011SMarcel Moolenaar 2553955d011SMarcel Moolenaar /* find the inode of the current directory */ 2563955d011SMarcel Moolenaar if (lstat(".", &st_cur) == -1) { 2573955d011SMarcel Moolenaar (void)sprintf(pathname, 2583955d011SMarcel Moolenaar "getwd: Cannot stat \".\" (%s)", strerror(errno)); 2593955d011SMarcel Moolenaar return NULL; 2603955d011SMarcel Moolenaar } 2613955d011SMarcel Moolenaar nextpathptr = strrcpy(nextpathptr, "../"); 2623955d011SMarcel Moolenaar 2633955d011SMarcel Moolenaar /* Descend to root */ 2643955d011SMarcel Moolenaar for (;;) { 2653955d011SMarcel Moolenaar 2663955d011SMarcel Moolenaar /* look if we found root yet */ 2673955d011SMarcel Moolenaar if (st_cur.st_ino == st_root.st_ino && 2683955d011SMarcel Moolenaar DEV_DEV_COMPARE(st_cur.st_dev, st_root.st_dev)) { 2693955d011SMarcel Moolenaar (void)strcpy(pathname, *pathptr != '/' ? "/" : pathptr); 2703841c287SSimon J. Gerraty return pathname; 2713955d011SMarcel Moolenaar } 2723955d011SMarcel Moolenaar 2733955d011SMarcel Moolenaar /* open the parent directory */ 2743955d011SMarcel Moolenaar if (stat(nextpathptr, &st_dotdot) == -1) { 2753955d011SMarcel Moolenaar (void)sprintf(pathname, 2763955d011SMarcel Moolenaar "getwd: Cannot stat directory \"%s\" (%s)", 2773955d011SMarcel Moolenaar nextpathptr, strerror(errno)); 2783955d011SMarcel Moolenaar return NULL; 2793955d011SMarcel Moolenaar } 2803955d011SMarcel Moolenaar if ((dp = opendir(nextpathptr)) == NULL) { 2813955d011SMarcel Moolenaar (void)sprintf(pathname, 2823955d011SMarcel Moolenaar "getwd: Cannot open directory \"%s\" (%s)", 2833955d011SMarcel Moolenaar nextpathptr, strerror(errno)); 2843955d011SMarcel Moolenaar return NULL; 2853955d011SMarcel Moolenaar } 2863955d011SMarcel Moolenaar 2873955d011SMarcel Moolenaar /* look in the parent for the entry with the same inode */ 2883955d011SMarcel Moolenaar if (DEV_DEV_COMPARE(st_dotdot.st_dev, st_cur.st_dev)) { 2893955d011SMarcel Moolenaar /* Parent has same device. No need to stat every member */ 2903955d011SMarcel Moolenaar for (d = readdir(dp); d != NULL; d = readdir(dp)) 2913955d011SMarcel Moolenaar if (d->d_fileno == st_cur.st_ino) 2923955d011SMarcel Moolenaar break; 293e2eeea75SSimon J. Gerraty } else { 2943955d011SMarcel Moolenaar /* 2953955d011SMarcel Moolenaar * Parent has a different device. This is a mount point so we 2963955d011SMarcel Moolenaar * need to stat every member 2973955d011SMarcel Moolenaar */ 2983955d011SMarcel Moolenaar for (d = readdir(dp); d != NULL; d = readdir(dp)) { 2993955d011SMarcel Moolenaar if (ISDOT(d->d_name) || ISDOTDOT(d->d_name)) 3003955d011SMarcel Moolenaar continue; 3013955d011SMarcel Moolenaar (void)strcpy(cur_name_add, d->d_name); 3023955d011SMarcel Moolenaar if (lstat(nextpathptr, &st_next) == -1) { 3033955d011SMarcel Moolenaar (void)sprintf(pathname, 3043955d011SMarcel Moolenaar "getwd: Cannot stat \"%s\" (%s)", 3053955d011SMarcel Moolenaar d->d_name, strerror(errno)); 3063955d011SMarcel Moolenaar (void)closedir(dp); 3073955d011SMarcel Moolenaar return NULL; 3083955d011SMarcel Moolenaar } 3093955d011SMarcel Moolenaar /* check if we found it yet */ 3103955d011SMarcel Moolenaar if (st_next.st_ino == st_cur.st_ino && 3113955d011SMarcel Moolenaar DEV_DEV_COMPARE(st_next.st_dev, st_cur.st_dev)) 3123955d011SMarcel Moolenaar break; 3133955d011SMarcel Moolenaar } 3143955d011SMarcel Moolenaar } 3153955d011SMarcel Moolenaar if (d == NULL) { 3163955d011SMarcel Moolenaar (void)sprintf(pathname, 3173955d011SMarcel Moolenaar "getwd: Cannot find \".\" in \"..\""); 3183955d011SMarcel Moolenaar (void)closedir(dp); 3193955d011SMarcel Moolenaar return NULL; 3203955d011SMarcel Moolenaar } 3213955d011SMarcel Moolenaar st_cur = st_dotdot; 3223955d011SMarcel Moolenaar pathptr = strrcpy(pathptr, d->d_name); 3233955d011SMarcel Moolenaar pathptr = strrcpy(pathptr, "/"); 3243955d011SMarcel Moolenaar nextpathptr = strrcpy(nextpathptr, "../"); 3253955d011SMarcel Moolenaar (void)closedir(dp); 3263955d011SMarcel Moolenaar *cur_name_add = '\0'; 3273955d011SMarcel Moolenaar } 3283955d011SMarcel Moolenaar } /* end getwd */ 3293955d011SMarcel Moolenaar 3303955d011SMarcel Moolenaar #endif /* __hpux */ 3313955d011SMarcel Moolenaar 3323955d011SMarcel Moolenaar #if !defined(HAVE_GETCWD) 3333955d011SMarcel Moolenaar char * 3343955d011SMarcel Moolenaar getcwd(path, sz) 3353955d011SMarcel Moolenaar char *path; 3363955d011SMarcel Moolenaar int sz; 3373955d011SMarcel Moolenaar { 3383955d011SMarcel Moolenaar return getwd(path); 3393955d011SMarcel Moolenaar } 3403955d011SMarcel Moolenaar #endif 3413955d011SMarcel Moolenaar 34212904384SSimon J. Gerraty #if !defined(HAVE_SIGACTION) 34312904384SSimon J. Gerraty #include "sigact.h" 34412904384SSimon J. Gerraty #endif 34512904384SSimon J. Gerraty 3463955d011SMarcel Moolenaar /* force posix signals */ 347956e45f6SSimon J. Gerraty SignalProc 348956e45f6SSimon J. Gerraty bmake_signal(int s, SignalProc a) 3493955d011SMarcel Moolenaar { 3503955d011SMarcel Moolenaar struct sigaction sa, osa; 3513955d011SMarcel Moolenaar 3523955d011SMarcel Moolenaar sa.sa_handler = a; 3533955d011SMarcel Moolenaar sigemptyset(&sa.sa_mask); 3543955d011SMarcel Moolenaar sa.sa_flags = SA_RESTART; 3553955d011SMarcel Moolenaar 3563955d011SMarcel Moolenaar if (sigaction(s, &sa, &osa) == -1) 3573955d011SMarcel Moolenaar return SIG_ERR; 3583955d011SMarcel Moolenaar else 3593955d011SMarcel Moolenaar return osa.sa_handler; 3603955d011SMarcel Moolenaar } 3613955d011SMarcel Moolenaar 3623955d011SMarcel Moolenaar #if !defined(HAVE_VSNPRINTF) || !defined(HAVE_VASPRINTF) 3633955d011SMarcel Moolenaar #include <stdarg.h> 3643955d011SMarcel Moolenaar #endif 3653955d011SMarcel Moolenaar 3663955d011SMarcel Moolenaar #if !defined(HAVE_VSNPRINTF) 3673955d011SMarcel Moolenaar #if !defined(__osf__) 3683955d011SMarcel Moolenaar #ifdef _IOSTRG 3693955d011SMarcel Moolenaar #define STRFLAG (_IOSTRG|_IOWRT) /* no _IOWRT: avoid stdio bug */ 3703955d011SMarcel Moolenaar #else 3713955d011SMarcel Moolenaar #if 0 3723955d011SMarcel Moolenaar #define STRFLAG (_IOREAD) /* XXX: Assume svr4 stdio */ 3733955d011SMarcel Moolenaar #endif 3743955d011SMarcel Moolenaar #endif /* _IOSTRG */ 3753955d011SMarcel Moolenaar #endif /* __osf__ */ 3763955d011SMarcel Moolenaar 3773955d011SMarcel Moolenaar int 3783955d011SMarcel Moolenaar vsnprintf(char *s, size_t n, const char *fmt, va_list args) 3793955d011SMarcel Moolenaar { 3803955d011SMarcel Moolenaar #ifdef STRFLAG 3813955d011SMarcel Moolenaar FILE fakebuf; 3823955d011SMarcel Moolenaar 3833955d011SMarcel Moolenaar fakebuf._flag = STRFLAG; 3843955d011SMarcel Moolenaar /* 3853955d011SMarcel Moolenaar * Some os's are char * _ptr, others are unsigned char *_ptr... 3863955d011SMarcel Moolenaar * We cast to void * to make everyone happy. 3873955d011SMarcel Moolenaar */ 3883955d011SMarcel Moolenaar fakebuf._ptr = (void *)s; 3893955d011SMarcel Moolenaar fakebuf._cnt = n - 1; 3903955d011SMarcel Moolenaar fakebuf._file = -1; 3913955d011SMarcel Moolenaar _doprnt(fmt, args, &fakebuf); 3923955d011SMarcel Moolenaar fakebuf._cnt++; 3933955d011SMarcel Moolenaar putc('\0', &fakebuf); 3943955d011SMarcel Moolenaar if (fakebuf._cnt < 0) 3953955d011SMarcel Moolenaar fakebuf._cnt = 0; 3963841c287SSimon J. Gerraty return n - fakebuf._cnt - 1; 3973955d011SMarcel Moolenaar #else 3983955d011SMarcel Moolenaar #ifndef _PATH_DEVNULL 3993955d011SMarcel Moolenaar # define _PATH_DEVNULL "/dev/null" 4003955d011SMarcel Moolenaar #endif 4013955d011SMarcel Moolenaar /* 4023955d011SMarcel Moolenaar * Rats... we don't want to clobber anything... 4033955d011SMarcel Moolenaar * do a printf to /dev/null to see how much space we need. 4043955d011SMarcel Moolenaar */ 4053955d011SMarcel Moolenaar static FILE *nullfp; 4063955d011SMarcel Moolenaar int need = 0; /* XXX what's a useful error return? */ 4073955d011SMarcel Moolenaar 4083955d011SMarcel Moolenaar if (!nullfp) 4093955d011SMarcel Moolenaar nullfp = fopen(_PATH_DEVNULL, "w"); 4103955d011SMarcel Moolenaar if (nullfp) { 4113955d011SMarcel Moolenaar need = vfprintf(nullfp, fmt, args); 4123955d011SMarcel Moolenaar if (need < n) 4133955d011SMarcel Moolenaar (void)vsprintf(s, fmt, args); 4143955d011SMarcel Moolenaar } 4153955d011SMarcel Moolenaar return need; 4163955d011SMarcel Moolenaar #endif 4173955d011SMarcel Moolenaar } 4183955d011SMarcel Moolenaar #endif 4193955d011SMarcel Moolenaar 4203955d011SMarcel Moolenaar #if !defined(HAVE_SNPRINTF) 4213955d011SMarcel Moolenaar int 4223955d011SMarcel Moolenaar snprintf(char *s, size_t n, const char *fmt, ...) 4233955d011SMarcel Moolenaar { 4243955d011SMarcel Moolenaar va_list ap; 4253955d011SMarcel Moolenaar int rv; 4263955d011SMarcel Moolenaar 4273955d011SMarcel Moolenaar va_start(ap, fmt); 4283955d011SMarcel Moolenaar rv = vsnprintf(s, n, fmt, ap); 4293955d011SMarcel Moolenaar va_end(ap); 4303955d011SMarcel Moolenaar return rv; 4313955d011SMarcel Moolenaar } 4323955d011SMarcel Moolenaar #endif 4333955d011SMarcel Moolenaar 434*d5e0a182SSimon J. Gerraty #if !defined(HAVE_STRFTIME) || defined(FORCE_BMAKE_STRFTIME) 435*d5e0a182SSimon J. Gerraty /* we only implement enough to pass our unit-tests */ 4363955d011SMarcel Moolenaar size_t 4373955d011SMarcel Moolenaar strftime(char *buf, size_t len, const char *fmt, const struct tm *tm) 4383955d011SMarcel Moolenaar { 439*d5e0a182SSimon J. Gerraty static const char *months[] = { 440*d5e0a182SSimon J. Gerraty "January", "February", "March", 441*d5e0a182SSimon J. Gerraty "April", "May", "June", 442*d5e0a182SSimon J. Gerraty "July", "August", "September", 443*d5e0a182SSimon J. Gerraty "October", "November", "December" 4443955d011SMarcel Moolenaar }; 445*d5e0a182SSimon J. Gerraty static const char *days[] = { 446*d5e0a182SSimon J. Gerraty "Sunday", "Monday", "Tuesday", "Wednesday", 447*d5e0a182SSimon J. Gerraty "Thursday", "Friday", "Saturday" 448*d5e0a182SSimon J. Gerraty }; 449*d5e0a182SSimon J. Gerraty int i; 4503955d011SMarcel Moolenaar size_t s; 4513955d011SMarcel Moolenaar char *b = buf; 452*d5e0a182SSimon J. Gerraty char *cp; 4533955d011SMarcel Moolenaar 454*d5e0a182SSimon J. Gerraty if (fmt == NULL || *fmt == '\0') 455*d5e0a182SSimon J. Gerraty fmt = "%c"; 4563955d011SMarcel Moolenaar while (*fmt) { 4573955d011SMarcel Moolenaar if (len == 0) 4583955d011SMarcel Moolenaar return buf - b; 4593955d011SMarcel Moolenaar if (*fmt != '%') { 4603955d011SMarcel Moolenaar *buf++ = *fmt++; 4613955d011SMarcel Moolenaar len--; 4623955d011SMarcel Moolenaar continue; 4633955d011SMarcel Moolenaar } 464*d5e0a182SSimon J. Gerraty fmt++; 4653955d011SMarcel Moolenaar switch (*fmt++) { 4663955d011SMarcel Moolenaar case '%': 4673955d011SMarcel Moolenaar *buf++ = '%'; 4683955d011SMarcel Moolenaar len--; 4693955d011SMarcel Moolenaar if (len == 0) return buf - b; 4703955d011SMarcel Moolenaar /*FALLTHROUGH*/ 4713955d011SMarcel Moolenaar case '\0': 4723955d011SMarcel Moolenaar *buf = '%'; 4733955d011SMarcel Moolenaar s = 1; 4743955d011SMarcel Moolenaar break; 475*d5e0a182SSimon J. Gerraty case 'A': 476*d5e0a182SSimon J. Gerraty s = snprintf(buf, len, "%s", days[tm->tm_wday]); 477*d5e0a182SSimon J. Gerraty break; 478*d5e0a182SSimon J. Gerraty case 'a': 479*d5e0a182SSimon J. Gerraty s = snprintf(buf, len, "%.3s", days[tm->tm_wday]); 480*d5e0a182SSimon J. Gerraty break; 481*d5e0a182SSimon J. Gerraty case 'B': 482*d5e0a182SSimon J. Gerraty if (tm->tm_mon >= 12) 483*d5e0a182SSimon J. Gerraty return buf - b; 484*d5e0a182SSimon J. Gerraty s = snprintf(buf, len, "%s", months[tm->tm_mon]); 485*d5e0a182SSimon J. Gerraty break; 486*d5e0a182SSimon J. Gerraty case 'b': 487*d5e0a182SSimon J. Gerraty if (tm->tm_mon >= 12) 488*d5e0a182SSimon J. Gerraty return buf - b; 489*d5e0a182SSimon J. Gerraty s = snprintf(buf, len, "%.3s", months[tm->tm_mon]); 490*d5e0a182SSimon J. Gerraty break; 491*d5e0a182SSimon J. Gerraty case 'c': 492*d5e0a182SSimon J. Gerraty s = strftime(buf, len, "%a %b %e %H:%M:%S %Y", tm); 493*d5e0a182SSimon J. Gerraty break; 494*d5e0a182SSimon J. Gerraty case 'd': 495*d5e0a182SSimon J. Gerraty s = snprintf(buf, len, "%02d", tm->tm_mday); 496*d5e0a182SSimon J. Gerraty break; 497*d5e0a182SSimon J. Gerraty case 'e': 498*d5e0a182SSimon J. Gerraty s = snprintf(buf, len, "%2d", tm->tm_mday); 499*d5e0a182SSimon J. Gerraty break; 500*d5e0a182SSimon J. Gerraty case 'F': 501*d5e0a182SSimon J. Gerraty s = strftime(buf, len, "%y-%m-%d", tm); 502*d5e0a182SSimon J. Gerraty break; 503*d5e0a182SSimon J. Gerraty case 'H': 504*d5e0a182SSimon J. Gerraty s = snprintf(buf, len, "%02d", tm->tm_hour); 505*d5e0a182SSimon J. Gerraty break; 506*d5e0a182SSimon J. Gerraty case 'I': 507*d5e0a182SSimon J. Gerraty if ((i = tm->tm_hour) == 0) 508*d5e0a182SSimon J. Gerraty i = 24; 509*d5e0a182SSimon J. Gerraty s = snprintf(buf, len, "%02d", (i > 12) ? (i - 12) : i); 510*d5e0a182SSimon J. Gerraty break; 511*d5e0a182SSimon J. Gerraty case 'j': 512*d5e0a182SSimon J. Gerraty s = snprintf(buf, len, "%03d", tm->tm_yday + 1); 513*d5e0a182SSimon J. Gerraty break; 5143955d011SMarcel Moolenaar case 'k': 5153955d011SMarcel Moolenaar s = snprintf(buf, len, "%d", tm->tm_hour); 5163955d011SMarcel Moolenaar break; 5173955d011SMarcel Moolenaar case 'M': 5183955d011SMarcel Moolenaar s = snprintf(buf, len, "%02d", tm->tm_min); 5193955d011SMarcel Moolenaar break; 520*d5e0a182SSimon J. Gerraty case 'm': 521*d5e0a182SSimon J. Gerraty s = snprintf(buf, len, "%02d", 1 + tm->tm_mon); 522*d5e0a182SSimon J. Gerraty break; 5233955d011SMarcel Moolenaar case 'S': 5243955d011SMarcel Moolenaar s = snprintf(buf, len, "%02d", tm->tm_sec); 5253955d011SMarcel Moolenaar break; 526*d5e0a182SSimon J. Gerraty case 's': 527*d5e0a182SSimon J. Gerraty s = snprintf(buf, len, "%ld", (long)time(NULL)); 5283955d011SMarcel Moolenaar break; 529*d5e0a182SSimon J. Gerraty case 'T': 530*d5e0a182SSimon J. Gerraty s = strftime(buf, len, "%H:%M:%S", tm); 531*d5e0a182SSimon J. Gerraty break; 532*d5e0a182SSimon J. Gerraty case 'w': 533*d5e0a182SSimon J. Gerraty s = snprintf(buf, len, "%02d", tm->tm_wday); 5343955d011SMarcel Moolenaar break; 5353955d011SMarcel Moolenaar case 'Y': 5363955d011SMarcel Moolenaar s = snprintf(buf, len, "%d", 1900 + tm->tm_year); 5373955d011SMarcel Moolenaar break; 538*d5e0a182SSimon J. Gerraty case 'y': 539*d5e0a182SSimon J. Gerraty s = snprintf(buf, len, "%02d", tm->tm_year % 100); 540*d5e0a182SSimon J. Gerraty break; 541*d5e0a182SSimon J. Gerraty case 'Z': 542*d5e0a182SSimon J. Gerraty if ((cp = getenv("TZ")) != NULL) { 543*d5e0a182SSimon J. Gerraty char tz[20]; 544*d5e0a182SSimon J. Gerraty 545*d5e0a182SSimon J. Gerraty i = snprintf(tz, sizeof(tz), "%s", cp); 546*d5e0a182SSimon J. Gerraty if (i > 5) { 547*d5e0a182SSimon J. Gerraty cp = &tz[i - 3]; 548*d5e0a182SSimon J. Gerraty tz[3] = '\0'; 549*d5e0a182SSimon J. Gerraty } else 550*d5e0a182SSimon J. Gerraty cp = tz; 551*d5e0a182SSimon J. Gerraty s = snprintf(buf, len, "%s", 552*d5e0a182SSimon J. Gerraty tm->tm_isdst ? cp : tz); 553*d5e0a182SSimon J. Gerraty } else 554*d5e0a182SSimon J. Gerraty s = 0; 555*d5e0a182SSimon J. Gerraty break; 5563955d011SMarcel Moolenaar default: 5573955d011SMarcel Moolenaar s = snprintf(buf, len, "Unsupported format %c", 5583955d011SMarcel Moolenaar fmt[-1]); 5593955d011SMarcel Moolenaar break; 5603955d011SMarcel Moolenaar } 5613955d011SMarcel Moolenaar buf += s; 5623955d011SMarcel Moolenaar len -= s; 5633955d011SMarcel Moolenaar } 564956e45f6SSimon J. Gerraty return buf - b; 5653955d011SMarcel Moolenaar } 5663955d011SMarcel Moolenaar #endif 5673955d011SMarcel Moolenaar 5683955d011SMarcel Moolenaar #if !defined(HAVE_KILLPG) 5693955d011SMarcel Moolenaar #if !defined(__hpux__) && !defined(__hpux) 5703955d011SMarcel Moolenaar int 5713955d011SMarcel Moolenaar killpg(int pid, int sig) 5723955d011SMarcel Moolenaar { 5733955d011SMarcel Moolenaar return kill(-pid, sig); 5743955d011SMarcel Moolenaar } 5753955d011SMarcel Moolenaar #endif 5763955d011SMarcel Moolenaar #endif 5773955d011SMarcel Moolenaar 5783955d011SMarcel Moolenaar #if !defined(HAVE_WARNX) 5793955d011SMarcel Moolenaar static void 5803955d011SMarcel Moolenaar vwarnx(const char *fmt, va_list args) 5813955d011SMarcel Moolenaar { 5823955d011SMarcel Moolenaar fprintf(stderr, "%s: ", progname); 5833955d011SMarcel Moolenaar if ((fmt)) { 5843955d011SMarcel Moolenaar vfprintf(stderr, fmt, args); 5853955d011SMarcel Moolenaar fprintf(stderr, ": "); 5863955d011SMarcel Moolenaar } 5873955d011SMarcel Moolenaar } 5883955d011SMarcel Moolenaar #endif 5893955d011SMarcel Moolenaar 5903955d011SMarcel Moolenaar #if !defined(HAVE_WARN) 5913955d011SMarcel Moolenaar static void 5923955d011SMarcel Moolenaar vwarn(const char *fmt, va_list args) 5933955d011SMarcel Moolenaar { 5943955d011SMarcel Moolenaar vwarnx(fmt, args); 5953955d011SMarcel Moolenaar fprintf(stderr, "%s\n", strerror(errno)); 5963955d011SMarcel Moolenaar } 5973955d011SMarcel Moolenaar #endif 5983955d011SMarcel Moolenaar 5993955d011SMarcel Moolenaar #if !defined(HAVE_ERR) 6003955d011SMarcel Moolenaar static void 6013955d011SMarcel Moolenaar verr(int eval, const char *fmt, va_list args) 6023955d011SMarcel Moolenaar { 6033955d011SMarcel Moolenaar vwarn(fmt, args); 6043955d011SMarcel Moolenaar exit(eval); 6053955d011SMarcel Moolenaar } 6063955d011SMarcel Moolenaar #endif 6073955d011SMarcel Moolenaar 6083955d011SMarcel Moolenaar #if !defined(HAVE_ERRX) 6093955d011SMarcel Moolenaar static void 6103955d011SMarcel Moolenaar verrx(int eval, const char *fmt, va_list args) 6113955d011SMarcel Moolenaar { 6123955d011SMarcel Moolenaar vwarnx(fmt, args); 6133955d011SMarcel Moolenaar exit(eval); 6143955d011SMarcel Moolenaar } 6153955d011SMarcel Moolenaar #endif 6163955d011SMarcel Moolenaar 6173955d011SMarcel Moolenaar #if !defined(HAVE_ERR) 6183955d011SMarcel Moolenaar void 6193955d011SMarcel Moolenaar err(int eval, const char *fmt, ...) 6203955d011SMarcel Moolenaar { 6213955d011SMarcel Moolenaar va_list ap; 6223955d011SMarcel Moolenaar 6233955d011SMarcel Moolenaar va_start(ap, fmt); 6243955d011SMarcel Moolenaar verr(eval, fmt, ap); 6253955d011SMarcel Moolenaar va_end(ap); 6263955d011SMarcel Moolenaar } 6273955d011SMarcel Moolenaar #endif 6283955d011SMarcel Moolenaar 6293955d011SMarcel Moolenaar #if !defined(HAVE_ERRX) 6303955d011SMarcel Moolenaar void 6313955d011SMarcel Moolenaar errx(int eval, const char *fmt, ...) 6323955d011SMarcel Moolenaar { 6333955d011SMarcel Moolenaar va_list ap; 6343955d011SMarcel Moolenaar 6353955d011SMarcel Moolenaar va_start(ap, fmt); 6363955d011SMarcel Moolenaar verrx(eval, fmt, ap); 6373955d011SMarcel Moolenaar va_end(ap); 6383955d011SMarcel Moolenaar } 6393955d011SMarcel Moolenaar #endif 6403955d011SMarcel Moolenaar 6413955d011SMarcel Moolenaar #if !defined(HAVE_WARN) 6423955d011SMarcel Moolenaar void 6433955d011SMarcel Moolenaar warn(const char *fmt, ...) 6443955d011SMarcel Moolenaar { 6453955d011SMarcel Moolenaar va_list ap; 6463955d011SMarcel Moolenaar 6473955d011SMarcel Moolenaar va_start(ap, fmt); 6483955d011SMarcel Moolenaar vwarn(fmt, ap); 6493955d011SMarcel Moolenaar va_end(ap); 6503955d011SMarcel Moolenaar } 6513955d011SMarcel Moolenaar #endif 6523955d011SMarcel Moolenaar 6533955d011SMarcel Moolenaar #if !defined(HAVE_WARNX) 6543955d011SMarcel Moolenaar void 6553955d011SMarcel Moolenaar warnx(const char *fmt, ...) 6563955d011SMarcel Moolenaar { 6573955d011SMarcel Moolenaar va_list ap; 6583955d011SMarcel Moolenaar 6593955d011SMarcel Moolenaar va_start(ap, fmt); 6603955d011SMarcel Moolenaar vwarnx(fmt, ap); 6613955d011SMarcel Moolenaar va_end(ap); 6623955d011SMarcel Moolenaar } 6633955d011SMarcel Moolenaar #endif 66412904384SSimon J. Gerraty 66512904384SSimon J. Gerraty #ifdef HAVE_INTTYPES_H 66612904384SSimon J. Gerraty #include <inttypes.h> 66712904384SSimon J. Gerraty #elif defined(HAVE_STDINT_H) 66812904384SSimon J. Gerraty #include <stdint.h> 66912904384SSimon J. Gerraty #endif 67012904384SSimon J. Gerraty #ifdef HAVE_LIMITS_H 67112904384SSimon J. Gerraty #include <limits.h> 67212904384SSimon J. Gerraty #endif 67312904384SSimon J. Gerraty 67412904384SSimon J. Gerraty #ifndef NUM_TYPE 67512904384SSimon J. Gerraty # ifdef HAVE_LONG_LONG_INT 67612904384SSimon J. Gerraty # define NUM_TYPE long long 67712904384SSimon J. Gerraty # elif defined(_INT64_T_DECLARED) || defined(int64_t) 67812904384SSimon J. Gerraty # define NUM_TYPE int64_t 67912904384SSimon J. Gerraty # endif 68012904384SSimon J. Gerraty #endif 68112904384SSimon J. Gerraty 68212904384SSimon J. Gerraty #ifdef NUM_TYPE 68312904384SSimon J. Gerraty #if !defined(HAVE_STRTOLL) 68412904384SSimon J. Gerraty #define BCS_ONLY 68512904384SSimon J. Gerraty #define _FUNCNAME strtoll 68612904384SSimon J. Gerraty #define __INT NUM_TYPE 68712904384SSimon J. Gerraty #undef __INT_MIN 68812904384SSimon J. Gerraty #undef __INT_MAX 68912904384SSimon J. Gerraty #ifdef LLONG_MAX 69012904384SSimon J. Gerraty # define __INT_MIN LLONG_MIN 69112904384SSimon J. Gerraty # define __INT_MAX LLONG_MAX 69212904384SSimon J. Gerraty #elif defined(INT64_MAX) 69312904384SSimon J. Gerraty # define __INT_MIN INT64_MIN 69412904384SSimon J. Gerraty # define __INT_MAX INT64_MAX 69512904384SSimon J. Gerraty #endif 69612904384SSimon J. Gerraty #ifndef _DIAGASSERT 69712904384SSimon J. Gerraty # define _DIAGASSERT(e) 69812904384SSimon J. Gerraty #endif 69912904384SSimon J. Gerraty #ifndef __UNCONST 70012904384SSimon J. Gerraty # define __UNCONST(a) ((void *)(unsigned long)(const void *)(a)) 70112904384SSimon J. Gerraty #endif 70212904384SSimon J. Gerraty #include "_strtol.h" 70312904384SSimon J. Gerraty #endif 70412904384SSimon J. Gerraty 70512904384SSimon J. Gerraty #endif 70612904384SSimon J. Gerraty 70712904384SSimon J. Gerraty #if !defined(HAVE_STRTOL) 70812904384SSimon J. Gerraty #define BCS_ONLY 70912904384SSimon J. Gerraty #define _FUNCNAME strtol 71012904384SSimon J. Gerraty #define __INT long 71112904384SSimon J. Gerraty #undef __INT_MIN 71212904384SSimon J. Gerraty #undef __INT_MAX 71312904384SSimon J. Gerraty #define __INT_MIN LONG_MIN 71412904384SSimon J. Gerraty #define __INT_MAX LONG_MAX 71512904384SSimon J. Gerraty #ifndef _DIAGASSERT 71612904384SSimon J. Gerraty # define _DIAGASSERT(e) 71712904384SSimon J. Gerraty #endif 71812904384SSimon J. Gerraty #ifndef __UNCONST 71912904384SSimon J. Gerraty # define __UNCONST(a) ((void *)(unsigned long)(const void *)(a)) 72012904384SSimon J. Gerraty #endif 72112904384SSimon J. Gerraty #include "_strtol.h" 72212904384SSimon J. Gerraty #endif 72312904384SSimon J. Gerraty 72412904384SSimon J. Gerraty #if !defined(HAVE_STRTOUL) 72512904384SSimon J. Gerraty #define BCS_ONLY 72612904384SSimon J. Gerraty #define _FUNCNAME strtoul 72712904384SSimon J. Gerraty #define __INT unsigned long 72812904384SSimon J. Gerraty #undef __INT_MIN 72912904384SSimon J. Gerraty #undef __INT_MAX 73012904384SSimon J. Gerraty #define __INT_MIN 0 73112904384SSimon J. Gerraty #define __INT_MAX ULONG_MAX 73212904384SSimon J. Gerraty #ifndef _DIAGASSERT 73312904384SSimon J. Gerraty # define _DIAGASSERT(e) 73412904384SSimon J. Gerraty #endif 73512904384SSimon J. Gerraty #ifndef __UNCONST 73612904384SSimon J. Gerraty # define __UNCONST(a) ((void *)(unsigned long)(const void *)(a)) 73712904384SSimon J. Gerraty #endif 73812904384SSimon J. Gerraty #include "_strtol.h" 73912904384SSimon J. Gerraty #endif 740