1*dba7b0efSSimon J. Gerraty /* $NetBSD: util.c,v 1.76 2021/02/03 08:00:36 rillig Exp $ */ 23955d011SMarcel Moolenaar 33955d011SMarcel Moolenaar /* 43955d011SMarcel Moolenaar * Missing stuff from OS's 53955d011SMarcel Moolenaar * 6*dba7b0efSSimon J. Gerraty * $Id: util.c,v 1.46 2021/02/05 20:02:29 sjg Exp $ 73955d011SMarcel Moolenaar */ 83955d011SMarcel Moolenaar 9956e45f6SSimon J. Gerraty #include <sys/param.h> 103955d011SMarcel Moolenaar #include <errno.h> 113955d011SMarcel Moolenaar #include <time.h> 123955d011SMarcel Moolenaar #include <signal.h> 133955d011SMarcel Moolenaar 14956e45f6SSimon J. Gerraty #include "make.h" 15956e45f6SSimon J. Gerraty 16*dba7b0efSSimon J. Gerraty MAKE_RCSID("$NetBSD: util.c,v 1.76 2021/02/03 08:00:36 rillig Exp $"); 17956e45f6SSimon J. Gerraty 18956e45f6SSimon J. Gerraty #if !defined(MAKE_NATIVE) && !defined(HAVE_STRERROR) 193955d011SMarcel Moolenaar extern int errno, sys_nerr; 203955d011SMarcel Moolenaar extern char *sys_errlist[]; 213955d011SMarcel Moolenaar 223955d011SMarcel Moolenaar char * 233955d011SMarcel Moolenaar strerror(int e) 243955d011SMarcel Moolenaar { 253955d011SMarcel Moolenaar static char buf[100]; 263955d011SMarcel Moolenaar if (e < 0 || e >= sys_nerr) { 27e2eeea75SSimon J. Gerraty snprintf(buf, sizeof buf, "Unknown error %d", e); 283955d011SMarcel Moolenaar return buf; 29e2eeea75SSimon J. Gerraty } else 303955d011SMarcel Moolenaar return sys_errlist[e]; 313955d011SMarcel Moolenaar } 323955d011SMarcel Moolenaar #endif 333955d011SMarcel Moolenaar 343955d011SMarcel Moolenaar #if !defined(HAVE_GETENV) || !defined(HAVE_SETENV) || !defined(HAVE_UNSETENV) 353955d011SMarcel Moolenaar extern char **environ; 363955d011SMarcel Moolenaar 373955d011SMarcel Moolenaar static char * 383955d011SMarcel Moolenaar findenv(const char *name, int *offset) 393955d011SMarcel Moolenaar { 403955d011SMarcel Moolenaar size_t i, len; 413955d011SMarcel Moolenaar char *p, *q; 423955d011SMarcel Moolenaar 433955d011SMarcel Moolenaar len = strlen(name); 443955d011SMarcel Moolenaar for (i = 0; (q = environ[i]); i++) { 453955d011SMarcel Moolenaar p = strchr(q, '='); 463955d011SMarcel Moolenaar if (p == NULL || p - q != len) 473955d011SMarcel Moolenaar continue; 483955d011SMarcel Moolenaar if (strncmp(name, q, len) == 0) { 493955d011SMarcel Moolenaar *offset = i; 503955d011SMarcel Moolenaar return q + len + 1; 513955d011SMarcel Moolenaar } 523955d011SMarcel Moolenaar } 533955d011SMarcel Moolenaar *offset = i; 543955d011SMarcel Moolenaar return NULL; 553955d011SMarcel Moolenaar } 563955d011SMarcel Moolenaar 573955d011SMarcel Moolenaar char * 583955d011SMarcel Moolenaar getenv(const char *name) 593955d011SMarcel Moolenaar { 603955d011SMarcel Moolenaar int offset; 613955d011SMarcel Moolenaar 623841c287SSimon J. Gerraty return findenv(name, &offset); 633955d011SMarcel Moolenaar } 643955d011SMarcel Moolenaar 653955d011SMarcel Moolenaar int 663955d011SMarcel Moolenaar unsetenv(const char *name) 673955d011SMarcel Moolenaar { 683955d011SMarcel Moolenaar char **p; 693955d011SMarcel Moolenaar int offset; 703955d011SMarcel Moolenaar 713955d011SMarcel Moolenaar if (name == NULL || *name == '\0' || strchr(name, '=') != NULL) { 723955d011SMarcel Moolenaar errno = EINVAL; 733955d011SMarcel Moolenaar return -1; 743955d011SMarcel Moolenaar } 753955d011SMarcel Moolenaar 763955d011SMarcel Moolenaar while (findenv(name, &offset)) { /* if set multiple times */ 77*dba7b0efSSimon J. Gerraty for (p = &environ[offset];; p++) 783955d011SMarcel Moolenaar if (!(*p = *(p + 1))) 793955d011SMarcel Moolenaar break; 803955d011SMarcel Moolenaar } 813955d011SMarcel Moolenaar return 0; 823955d011SMarcel Moolenaar } 833955d011SMarcel Moolenaar 843955d011SMarcel Moolenaar int 853955d011SMarcel Moolenaar setenv(const char *name, const char *value, int rewrite) 863955d011SMarcel Moolenaar { 873955d011SMarcel Moolenaar char *c, **newenv; 883955d011SMarcel Moolenaar const char *cc; 893955d011SMarcel Moolenaar size_t l_value, size; 903955d011SMarcel Moolenaar int offset; 913955d011SMarcel Moolenaar 923955d011SMarcel Moolenaar if (name == NULL || value == NULL) { 933955d011SMarcel Moolenaar errno = EINVAL; 943955d011SMarcel Moolenaar return -1; 953955d011SMarcel Moolenaar } 963955d011SMarcel Moolenaar 973955d011SMarcel Moolenaar if (*value == '=') /* no `=' in value */ 98e2eeea75SSimon J. Gerraty value++; 993955d011SMarcel Moolenaar l_value = strlen(value); 1003955d011SMarcel Moolenaar 1013955d011SMarcel Moolenaar /* find if already exists */ 1023955d011SMarcel Moolenaar if ((c = findenv(name, &offset))) { 1033955d011SMarcel Moolenaar if (!rewrite) 1043955d011SMarcel Moolenaar return 0; 1053955d011SMarcel Moolenaar if (strlen(c) >= l_value) /* old larger; copy over */ 1063955d011SMarcel Moolenaar goto copy; 1073955d011SMarcel Moolenaar } else { /* create new slot */ 1083955d011SMarcel Moolenaar size = sizeof(char *) * (offset + 2); 1093955d011SMarcel Moolenaar if (savedEnv == environ) { /* just increase size */ 1103955d011SMarcel Moolenaar if ((newenv = realloc(savedEnv, size)) == NULL) 1113955d011SMarcel Moolenaar return -1; 1123955d011SMarcel Moolenaar savedEnv = newenv; 1133955d011SMarcel Moolenaar } else { /* get new space */ 1143955d011SMarcel Moolenaar /* 1153955d011SMarcel Moolenaar * We don't free here because we don't know if 1163955d011SMarcel Moolenaar * the first allocation is valid on all OS's 1173955d011SMarcel Moolenaar */ 1183955d011SMarcel Moolenaar if ((savedEnv = malloc(size)) == NULL) 1193955d011SMarcel Moolenaar return -1; 1203955d011SMarcel Moolenaar (void)memcpy(savedEnv, environ, size - sizeof(char *)); 1213955d011SMarcel Moolenaar } 1223955d011SMarcel Moolenaar environ = savedEnv; 1233955d011SMarcel Moolenaar environ[offset + 1] = NULL; 1243955d011SMarcel Moolenaar } 125*dba7b0efSSimon J. Gerraty for (cc = name; *cc && *cc != '='; cc++) /* no `=' in name */ 1263955d011SMarcel Moolenaar continue; 1273955d011SMarcel Moolenaar size = cc - name; 1283955d011SMarcel Moolenaar /* name + `=' + value */ 1293955d011SMarcel Moolenaar if ((environ[offset] = malloc(size + l_value + 2)) == NULL) 1303955d011SMarcel Moolenaar return -1; 1313955d011SMarcel Moolenaar c = environ[offset]; 1323955d011SMarcel Moolenaar (void)memcpy(c, name, size); 1333955d011SMarcel Moolenaar c += size; 1343955d011SMarcel Moolenaar *c++ = '='; 1353955d011SMarcel Moolenaar copy: 1363955d011SMarcel Moolenaar (void)memcpy(c, value, l_value + 1); 1373955d011SMarcel Moolenaar return 0; 1383955d011SMarcel Moolenaar } 1393955d011SMarcel Moolenaar 1403955d011SMarcel Moolenaar #ifdef TEST 1413955d011SMarcel Moolenaar int 1423955d011SMarcel Moolenaar main(int argc, char *argv[]) 1433955d011SMarcel Moolenaar { 1443955d011SMarcel Moolenaar setenv(argv[1], argv[2], 0); 1453955d011SMarcel Moolenaar printf("%s\n", getenv(argv[1])); 1463955d011SMarcel Moolenaar unsetenv(argv[1]); 1473955d011SMarcel Moolenaar printf("%s\n", getenv(argv[1])); 1483955d011SMarcel Moolenaar return 0; 1493955d011SMarcel Moolenaar } 1503955d011SMarcel Moolenaar #endif 1513955d011SMarcel Moolenaar 1523955d011SMarcel Moolenaar #endif 1533955d011SMarcel Moolenaar 1543955d011SMarcel Moolenaar 1553955d011SMarcel Moolenaar #if defined(__hpux__) || defined(__hpux) 15606b9b3e0SSimon J. Gerraty /* 15706b9b3e0SSimon J. Gerraty * strrcpy(): 1583955d011SMarcel Moolenaar * Like strcpy, going backwards and returning the new pointer 1593955d011SMarcel Moolenaar */ 1603955d011SMarcel Moolenaar static char * 1613955d011SMarcel Moolenaar strrcpy(char *ptr, char *str) 1623955d011SMarcel Moolenaar { 1633955d011SMarcel Moolenaar int len = strlen(str); 1643955d011SMarcel Moolenaar 16506b9b3e0SSimon J. Gerraty while (len != 0) 1663955d011SMarcel Moolenaar *--ptr = str[--len]; 1673955d011SMarcel Moolenaar 1683841c287SSimon J. Gerraty return ptr; 1693955d011SMarcel Moolenaar } /* end strrcpy */ 1703955d011SMarcel Moolenaar 1713955d011SMarcel Moolenaar 1723955d011SMarcel Moolenaar char *sys_siglist[] = { 1733955d011SMarcel Moolenaar "Signal 0", 1743955d011SMarcel Moolenaar "Hangup", /* SIGHUP */ 1753955d011SMarcel Moolenaar "Interrupt", /* SIGINT */ 1763955d011SMarcel Moolenaar "Quit", /* SIGQUIT */ 1773955d011SMarcel Moolenaar "Illegal instruction", /* SIGILL */ 1783955d011SMarcel Moolenaar "Trace/BPT trap", /* SIGTRAP */ 1793955d011SMarcel Moolenaar "IOT trap", /* SIGIOT */ 1803955d011SMarcel Moolenaar "EMT trap", /* SIGEMT */ 1813955d011SMarcel Moolenaar "Floating point exception", /* SIGFPE */ 1823955d011SMarcel Moolenaar "Killed", /* SIGKILL */ 1833955d011SMarcel Moolenaar "Bus error", /* SIGBUS */ 1843955d011SMarcel Moolenaar "Segmentation fault", /* SIGSEGV */ 1853955d011SMarcel Moolenaar "Bad system call", /* SIGSYS */ 1863955d011SMarcel Moolenaar "Broken pipe", /* SIGPIPE */ 1873955d011SMarcel Moolenaar "Alarm clock", /* SIGALRM */ 1883955d011SMarcel Moolenaar "Terminated", /* SIGTERM */ 1893955d011SMarcel Moolenaar "User defined signal 1", /* SIGUSR1 */ 1903955d011SMarcel Moolenaar "User defined signal 2", /* SIGUSR2 */ 1913955d011SMarcel Moolenaar "Child exited", /* SIGCLD */ 1923955d011SMarcel Moolenaar "Power-fail restart", /* SIGPWR */ 1933955d011SMarcel Moolenaar "Virtual timer expired", /* SIGVTALRM */ 1943955d011SMarcel Moolenaar "Profiling timer expired", /* SIGPROF */ 1953955d011SMarcel Moolenaar "I/O possible", /* SIGIO */ 1963955d011SMarcel Moolenaar "Window size changes", /* SIGWINDOW */ 1973955d011SMarcel Moolenaar "Stopped (signal)", /* SIGSTOP */ 1983955d011SMarcel Moolenaar "Stopped", /* SIGTSTP */ 1993955d011SMarcel Moolenaar "Continued", /* SIGCONT */ 2003955d011SMarcel Moolenaar "Stopped (tty input)", /* SIGTTIN */ 2013955d011SMarcel Moolenaar "Stopped (tty output)", /* SIGTTOU */ 2023955d011SMarcel Moolenaar "Urgent I/O condition", /* SIGURG */ 2033955d011SMarcel Moolenaar "Remote lock lost (NFS)", /* SIGLOST */ 2043955d011SMarcel Moolenaar "Signal 31", /* reserved */ 2053955d011SMarcel Moolenaar "DIL signal" /* SIGDIL */ 2063955d011SMarcel Moolenaar }; 2073955d011SMarcel Moolenaar #endif /* __hpux__ || __hpux */ 2083955d011SMarcel Moolenaar 2093955d011SMarcel Moolenaar #if defined(__hpux__) || defined(__hpux) 2103955d011SMarcel Moolenaar #include <sys/types.h> 2113955d011SMarcel Moolenaar #include <sys/syscall.h> 2123955d011SMarcel Moolenaar #include <sys/signal.h> 2133955d011SMarcel Moolenaar #include <sys/stat.h> 2143955d011SMarcel Moolenaar #include <dirent.h> 2153955d011SMarcel Moolenaar #include <sys/time.h> 2163955d011SMarcel Moolenaar #include <unistd.h> 2173955d011SMarcel Moolenaar 2183955d011SMarcel Moolenaar int 2193955d011SMarcel Moolenaar killpg(int pid, int sig) 2203955d011SMarcel Moolenaar { 2213955d011SMarcel Moolenaar return kill(-pid, sig); 2223955d011SMarcel Moolenaar } 2233955d011SMarcel Moolenaar 2243955d011SMarcel Moolenaar #if !defined(BSD) && !defined(d_fileno) 2253955d011SMarcel Moolenaar # define d_fileno d_ino 2263955d011SMarcel Moolenaar #endif 2273955d011SMarcel Moolenaar 2283955d011SMarcel Moolenaar #ifndef DEV_DEV_COMPARE 2293955d011SMarcel Moolenaar # define DEV_DEV_COMPARE(a, b) ((a) == (b)) 2303955d011SMarcel Moolenaar #endif 2313955d011SMarcel Moolenaar #define ISDOT(c) ((c)[0] == '.' && (((c)[1] == '\0') || ((c)[1] == '/'))) 2323955d011SMarcel Moolenaar #define ISDOTDOT(c) ((c)[0] == '.' && ISDOT(&((c)[1]))) 2333955d011SMarcel Moolenaar 2343955d011SMarcel Moolenaar char * 2353955d011SMarcel Moolenaar getwd(char *pathname) 2363955d011SMarcel Moolenaar { 2373955d011SMarcel Moolenaar DIR *dp; 2383955d011SMarcel Moolenaar struct dirent *d; 2393955d011SMarcel Moolenaar extern int errno; 2403955d011SMarcel Moolenaar 2413955d011SMarcel Moolenaar struct stat st_root, st_cur, st_next, st_dotdot; 2423955d011SMarcel Moolenaar char pathbuf[MAXPATHLEN], nextpathbuf[MAXPATHLEN * 2]; 2433955d011SMarcel Moolenaar char *pathptr, *nextpathptr, *cur_name_add; 2443955d011SMarcel Moolenaar 2453955d011SMarcel Moolenaar /* find the inode of root */ 2463955d011SMarcel Moolenaar if (stat("/", &st_root) == -1) { 2473955d011SMarcel Moolenaar (void)sprintf(pathname, 2483955d011SMarcel Moolenaar "getwd: Cannot stat \"/\" (%s)", strerror(errno)); 2493955d011SMarcel Moolenaar return NULL; 2503955d011SMarcel Moolenaar } 2513955d011SMarcel Moolenaar pathbuf[MAXPATHLEN - 1] = '\0'; 2523955d011SMarcel Moolenaar pathptr = &pathbuf[MAXPATHLEN - 1]; 2533955d011SMarcel Moolenaar nextpathbuf[MAXPATHLEN - 1] = '\0'; 2543955d011SMarcel Moolenaar cur_name_add = nextpathptr = &nextpathbuf[MAXPATHLEN - 1]; 2553955d011SMarcel Moolenaar 2563955d011SMarcel Moolenaar /* find the inode of the current directory */ 2573955d011SMarcel Moolenaar if (lstat(".", &st_cur) == -1) { 2583955d011SMarcel Moolenaar (void)sprintf(pathname, 2593955d011SMarcel Moolenaar "getwd: Cannot stat \".\" (%s)", strerror(errno)); 2603955d011SMarcel Moolenaar return NULL; 2613955d011SMarcel Moolenaar } 2623955d011SMarcel Moolenaar nextpathptr = strrcpy(nextpathptr, "../"); 2633955d011SMarcel Moolenaar 2643955d011SMarcel Moolenaar /* Descend to root */ 2653955d011SMarcel Moolenaar for (;;) { 2663955d011SMarcel Moolenaar 2673955d011SMarcel Moolenaar /* look if we found root yet */ 2683955d011SMarcel Moolenaar if (st_cur.st_ino == st_root.st_ino && 2693955d011SMarcel Moolenaar DEV_DEV_COMPARE(st_cur.st_dev, st_root.st_dev)) { 2703955d011SMarcel Moolenaar (void)strcpy(pathname, *pathptr != '/' ? "/" : pathptr); 2713841c287SSimon J. Gerraty return pathname; 2723955d011SMarcel Moolenaar } 2733955d011SMarcel Moolenaar 2743955d011SMarcel Moolenaar /* open the parent directory */ 2753955d011SMarcel Moolenaar if (stat(nextpathptr, &st_dotdot) == -1) { 2763955d011SMarcel Moolenaar (void)sprintf(pathname, 2773955d011SMarcel Moolenaar "getwd: Cannot stat directory \"%s\" (%s)", 2783955d011SMarcel Moolenaar nextpathptr, strerror(errno)); 2793955d011SMarcel Moolenaar return NULL; 2803955d011SMarcel Moolenaar } 2813955d011SMarcel Moolenaar if ((dp = opendir(nextpathptr)) == NULL) { 2823955d011SMarcel Moolenaar (void)sprintf(pathname, 2833955d011SMarcel Moolenaar "getwd: Cannot open directory \"%s\" (%s)", 2843955d011SMarcel Moolenaar nextpathptr, strerror(errno)); 2853955d011SMarcel Moolenaar return NULL; 2863955d011SMarcel Moolenaar } 2873955d011SMarcel Moolenaar 2883955d011SMarcel Moolenaar /* look in the parent for the entry with the same inode */ 2893955d011SMarcel Moolenaar if (DEV_DEV_COMPARE(st_dotdot.st_dev, st_cur.st_dev)) { 2903955d011SMarcel Moolenaar /* Parent has same device. No need to stat every member */ 2913955d011SMarcel Moolenaar for (d = readdir(dp); d != NULL; d = readdir(dp)) 2923955d011SMarcel Moolenaar if (d->d_fileno == st_cur.st_ino) 2933955d011SMarcel Moolenaar break; 294e2eeea75SSimon J. Gerraty } else { 2953955d011SMarcel Moolenaar /* 2963955d011SMarcel Moolenaar * Parent has a different device. This is a mount point so we 2973955d011SMarcel Moolenaar * need to stat every member 2983955d011SMarcel Moolenaar */ 2993955d011SMarcel Moolenaar for (d = readdir(dp); d != NULL; d = readdir(dp)) { 3003955d011SMarcel Moolenaar if (ISDOT(d->d_name) || ISDOTDOT(d->d_name)) 3013955d011SMarcel Moolenaar continue; 3023955d011SMarcel Moolenaar (void)strcpy(cur_name_add, d->d_name); 3033955d011SMarcel Moolenaar if (lstat(nextpathptr, &st_next) == -1) { 3043955d011SMarcel Moolenaar (void)sprintf(pathname, 3053955d011SMarcel Moolenaar "getwd: Cannot stat \"%s\" (%s)", 3063955d011SMarcel Moolenaar d->d_name, strerror(errno)); 3073955d011SMarcel Moolenaar (void)closedir(dp); 3083955d011SMarcel Moolenaar return NULL; 3093955d011SMarcel Moolenaar } 3103955d011SMarcel Moolenaar /* check if we found it yet */ 3113955d011SMarcel Moolenaar if (st_next.st_ino == st_cur.st_ino && 3123955d011SMarcel Moolenaar DEV_DEV_COMPARE(st_next.st_dev, st_cur.st_dev)) 3133955d011SMarcel Moolenaar break; 3143955d011SMarcel Moolenaar } 3153955d011SMarcel Moolenaar } 3163955d011SMarcel Moolenaar if (d == NULL) { 3173955d011SMarcel Moolenaar (void)sprintf(pathname, 3183955d011SMarcel Moolenaar "getwd: Cannot find \".\" in \"..\""); 3193955d011SMarcel Moolenaar (void)closedir(dp); 3203955d011SMarcel Moolenaar return NULL; 3213955d011SMarcel Moolenaar } 3223955d011SMarcel Moolenaar st_cur = st_dotdot; 3233955d011SMarcel Moolenaar pathptr = strrcpy(pathptr, d->d_name); 3243955d011SMarcel Moolenaar pathptr = strrcpy(pathptr, "/"); 3253955d011SMarcel Moolenaar nextpathptr = strrcpy(nextpathptr, "../"); 3263955d011SMarcel Moolenaar (void)closedir(dp); 3273955d011SMarcel Moolenaar *cur_name_add = '\0'; 3283955d011SMarcel Moolenaar } 3293955d011SMarcel Moolenaar } /* end getwd */ 3303955d011SMarcel Moolenaar 3313955d011SMarcel Moolenaar #endif /* __hpux */ 3323955d011SMarcel Moolenaar 3333955d011SMarcel Moolenaar #if !defined(HAVE_GETCWD) 3343955d011SMarcel Moolenaar char * 3353955d011SMarcel Moolenaar getcwd(path, sz) 3363955d011SMarcel Moolenaar char *path; 3373955d011SMarcel Moolenaar int sz; 3383955d011SMarcel Moolenaar { 3393955d011SMarcel Moolenaar return getwd(path); 3403955d011SMarcel Moolenaar } 3413955d011SMarcel Moolenaar #endif 3423955d011SMarcel Moolenaar 3433955d011SMarcel Moolenaar /* force posix signals */ 344956e45f6SSimon J. Gerraty SignalProc 345956e45f6SSimon J. Gerraty bmake_signal(int s, SignalProc a) 3463955d011SMarcel Moolenaar { 3473955d011SMarcel Moolenaar struct sigaction sa, osa; 3483955d011SMarcel Moolenaar 3493955d011SMarcel Moolenaar sa.sa_handler = a; 3503955d011SMarcel Moolenaar sigemptyset(&sa.sa_mask); 3513955d011SMarcel Moolenaar sa.sa_flags = SA_RESTART; 3523955d011SMarcel Moolenaar 3533955d011SMarcel Moolenaar if (sigaction(s, &sa, &osa) == -1) 3543955d011SMarcel Moolenaar return SIG_ERR; 3553955d011SMarcel Moolenaar else 3563955d011SMarcel Moolenaar return osa.sa_handler; 3573955d011SMarcel Moolenaar } 3583955d011SMarcel Moolenaar 3593955d011SMarcel Moolenaar #if !defined(HAVE_VSNPRINTF) || !defined(HAVE_VASPRINTF) 3603955d011SMarcel Moolenaar #include <stdarg.h> 3613955d011SMarcel Moolenaar #endif 3623955d011SMarcel Moolenaar 3633955d011SMarcel Moolenaar #if !defined(HAVE_VSNPRINTF) 3643955d011SMarcel Moolenaar #if !defined(__osf__) 3653955d011SMarcel Moolenaar #ifdef _IOSTRG 3663955d011SMarcel Moolenaar #define STRFLAG (_IOSTRG|_IOWRT) /* no _IOWRT: avoid stdio bug */ 3673955d011SMarcel Moolenaar #else 3683955d011SMarcel Moolenaar #if 0 3693955d011SMarcel Moolenaar #define STRFLAG (_IOREAD) /* XXX: Assume svr4 stdio */ 3703955d011SMarcel Moolenaar #endif 3713955d011SMarcel Moolenaar #endif /* _IOSTRG */ 3723955d011SMarcel Moolenaar #endif /* __osf__ */ 3733955d011SMarcel Moolenaar 3743955d011SMarcel Moolenaar int 3753955d011SMarcel Moolenaar vsnprintf(char *s, size_t n, const char *fmt, va_list args) 3763955d011SMarcel Moolenaar { 3773955d011SMarcel Moolenaar #ifdef STRFLAG 3783955d011SMarcel Moolenaar FILE fakebuf; 3793955d011SMarcel Moolenaar 3803955d011SMarcel Moolenaar fakebuf._flag = STRFLAG; 3813955d011SMarcel Moolenaar /* 3823955d011SMarcel Moolenaar * Some os's are char * _ptr, others are unsigned char *_ptr... 3833955d011SMarcel Moolenaar * We cast to void * to make everyone happy. 3843955d011SMarcel Moolenaar */ 3853955d011SMarcel Moolenaar fakebuf._ptr = (void *)s; 3863955d011SMarcel Moolenaar fakebuf._cnt = n - 1; 3873955d011SMarcel Moolenaar fakebuf._file = -1; 3883955d011SMarcel Moolenaar _doprnt(fmt, args, &fakebuf); 3893955d011SMarcel Moolenaar fakebuf._cnt++; 3903955d011SMarcel Moolenaar putc('\0', &fakebuf); 3913955d011SMarcel Moolenaar if (fakebuf._cnt < 0) 3923955d011SMarcel Moolenaar fakebuf._cnt = 0; 3933841c287SSimon J. Gerraty return n - fakebuf._cnt - 1; 3943955d011SMarcel Moolenaar #else 3953955d011SMarcel Moolenaar #ifndef _PATH_DEVNULL 3963955d011SMarcel Moolenaar # define _PATH_DEVNULL "/dev/null" 3973955d011SMarcel Moolenaar #endif 3983955d011SMarcel Moolenaar /* 3993955d011SMarcel Moolenaar * Rats... we don't want to clobber anything... 4003955d011SMarcel Moolenaar * do a printf to /dev/null to see how much space we need. 4013955d011SMarcel Moolenaar */ 4023955d011SMarcel Moolenaar static FILE *nullfp; 4033955d011SMarcel Moolenaar int need = 0; /* XXX what's a useful error return? */ 4043955d011SMarcel Moolenaar 4053955d011SMarcel Moolenaar if (!nullfp) 4063955d011SMarcel Moolenaar nullfp = fopen(_PATH_DEVNULL, "w"); 4073955d011SMarcel Moolenaar if (nullfp) { 4083955d011SMarcel Moolenaar need = vfprintf(nullfp, fmt, args); 4093955d011SMarcel Moolenaar if (need < n) 4103955d011SMarcel Moolenaar (void)vsprintf(s, fmt, args); 4113955d011SMarcel Moolenaar } 4123955d011SMarcel Moolenaar return need; 4133955d011SMarcel Moolenaar #endif 4143955d011SMarcel Moolenaar } 4153955d011SMarcel Moolenaar #endif 4163955d011SMarcel Moolenaar 4173955d011SMarcel Moolenaar #if !defined(HAVE_SNPRINTF) 4183955d011SMarcel Moolenaar int 4193955d011SMarcel Moolenaar snprintf(char *s, size_t n, const char *fmt, ...) 4203955d011SMarcel Moolenaar { 4213955d011SMarcel Moolenaar va_list ap; 4223955d011SMarcel Moolenaar int rv; 4233955d011SMarcel Moolenaar 4243955d011SMarcel Moolenaar va_start(ap, fmt); 4253955d011SMarcel Moolenaar rv = vsnprintf(s, n, fmt, ap); 4263955d011SMarcel Moolenaar va_end(ap); 4273955d011SMarcel Moolenaar return rv; 4283955d011SMarcel Moolenaar } 4293955d011SMarcel Moolenaar #endif 4303955d011SMarcel Moolenaar 4313955d011SMarcel Moolenaar #if !defined(HAVE_STRFTIME) 4323955d011SMarcel Moolenaar size_t 4333955d011SMarcel Moolenaar strftime(char *buf, size_t len, const char *fmt, const struct tm *tm) 4343955d011SMarcel Moolenaar { 4353955d011SMarcel Moolenaar static char months[][4] = { 4363955d011SMarcel Moolenaar "Jan", "Feb", "Mar", "Apr", "May", "Jun", 4373955d011SMarcel Moolenaar "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" 4383955d011SMarcel Moolenaar }; 4393955d011SMarcel Moolenaar 4403955d011SMarcel Moolenaar size_t s; 4413955d011SMarcel Moolenaar char *b = buf; 4423955d011SMarcel Moolenaar 4433955d011SMarcel Moolenaar while (*fmt) { 4443955d011SMarcel Moolenaar if (len == 0) 4453955d011SMarcel Moolenaar return buf - b; 4463955d011SMarcel Moolenaar if (*fmt != '%') { 4473955d011SMarcel Moolenaar *buf++ = *fmt++; 4483955d011SMarcel Moolenaar len--; 4493955d011SMarcel Moolenaar continue; 4503955d011SMarcel Moolenaar } 4513955d011SMarcel Moolenaar switch (*fmt++) { 4523955d011SMarcel Moolenaar case '%': 4533955d011SMarcel Moolenaar *buf++ = '%'; 4543955d011SMarcel Moolenaar len--; 4553955d011SMarcel Moolenaar if (len == 0) return buf - b; 4563955d011SMarcel Moolenaar /*FALLTHROUGH*/ 4573955d011SMarcel Moolenaar case '\0': 4583955d011SMarcel Moolenaar *buf = '%'; 4593955d011SMarcel Moolenaar s = 1; 4603955d011SMarcel Moolenaar break; 4613955d011SMarcel Moolenaar case 'k': 4623955d011SMarcel Moolenaar s = snprintf(buf, len, "%d", tm->tm_hour); 4633955d011SMarcel Moolenaar break; 4643955d011SMarcel Moolenaar case 'M': 4653955d011SMarcel Moolenaar s = snprintf(buf, len, "%02d", tm->tm_min); 4663955d011SMarcel Moolenaar break; 4673955d011SMarcel Moolenaar case 'S': 4683955d011SMarcel Moolenaar s = snprintf(buf, len, "%02d", tm->tm_sec); 4693955d011SMarcel Moolenaar break; 4703955d011SMarcel Moolenaar case 'b': 4713955d011SMarcel Moolenaar if (tm->tm_mon >= 12) 4723955d011SMarcel Moolenaar return buf - b; 4733955d011SMarcel Moolenaar s = snprintf(buf, len, "%s", months[tm->tm_mon]); 4743955d011SMarcel Moolenaar break; 4753955d011SMarcel Moolenaar case 'd': 4763955d011SMarcel Moolenaar s = snprintf(buf, len, "%02d", tm->tm_mday); 4773955d011SMarcel Moolenaar break; 4783955d011SMarcel Moolenaar case 'Y': 4793955d011SMarcel Moolenaar s = snprintf(buf, len, "%d", 1900 + tm->tm_year); 4803955d011SMarcel Moolenaar break; 4813955d011SMarcel Moolenaar default: 4823955d011SMarcel Moolenaar s = snprintf(buf, len, "Unsupported format %c", 4833955d011SMarcel Moolenaar fmt[-1]); 4843955d011SMarcel Moolenaar break; 4853955d011SMarcel Moolenaar } 4863955d011SMarcel Moolenaar buf += s; 4873955d011SMarcel Moolenaar len -= s; 4883955d011SMarcel Moolenaar } 489956e45f6SSimon J. Gerraty return buf - b; 4903955d011SMarcel Moolenaar } 4913955d011SMarcel Moolenaar #endif 4923955d011SMarcel Moolenaar 4933955d011SMarcel Moolenaar #if !defined(HAVE_KILLPG) 4943955d011SMarcel Moolenaar #if !defined(__hpux__) && !defined(__hpux) 4953955d011SMarcel Moolenaar int 4963955d011SMarcel Moolenaar killpg(int pid, int sig) 4973955d011SMarcel Moolenaar { 4983955d011SMarcel Moolenaar return kill(-pid, sig); 4993955d011SMarcel Moolenaar } 5003955d011SMarcel Moolenaar #endif 5013955d011SMarcel Moolenaar #endif 5023955d011SMarcel Moolenaar 5033955d011SMarcel Moolenaar #if !defined(HAVE_WARNX) 5043955d011SMarcel Moolenaar static void 5053955d011SMarcel Moolenaar vwarnx(const char *fmt, va_list args) 5063955d011SMarcel Moolenaar { 5073955d011SMarcel Moolenaar fprintf(stderr, "%s: ", progname); 5083955d011SMarcel Moolenaar if ((fmt)) { 5093955d011SMarcel Moolenaar vfprintf(stderr, fmt, args); 5103955d011SMarcel Moolenaar fprintf(stderr, ": "); 5113955d011SMarcel Moolenaar } 5123955d011SMarcel Moolenaar } 5133955d011SMarcel Moolenaar #endif 5143955d011SMarcel Moolenaar 5153955d011SMarcel Moolenaar #if !defined(HAVE_WARN) 5163955d011SMarcel Moolenaar static void 5173955d011SMarcel Moolenaar vwarn(const char *fmt, va_list args) 5183955d011SMarcel Moolenaar { 5193955d011SMarcel Moolenaar vwarnx(fmt, args); 5203955d011SMarcel Moolenaar fprintf(stderr, "%s\n", strerror(errno)); 5213955d011SMarcel Moolenaar } 5223955d011SMarcel Moolenaar #endif 5233955d011SMarcel Moolenaar 5243955d011SMarcel Moolenaar #if !defined(HAVE_ERR) 5253955d011SMarcel Moolenaar static void 5263955d011SMarcel Moolenaar verr(int eval, const char *fmt, va_list args) 5273955d011SMarcel Moolenaar { 5283955d011SMarcel Moolenaar vwarn(fmt, args); 5293955d011SMarcel Moolenaar exit(eval); 5303955d011SMarcel Moolenaar } 5313955d011SMarcel Moolenaar #endif 5323955d011SMarcel Moolenaar 5333955d011SMarcel Moolenaar #if !defined(HAVE_ERRX) 5343955d011SMarcel Moolenaar static void 5353955d011SMarcel Moolenaar verrx(int eval, const char *fmt, va_list args) 5363955d011SMarcel Moolenaar { 5373955d011SMarcel Moolenaar vwarnx(fmt, args); 5383955d011SMarcel Moolenaar exit(eval); 5393955d011SMarcel Moolenaar } 5403955d011SMarcel Moolenaar #endif 5413955d011SMarcel Moolenaar 5423955d011SMarcel Moolenaar #if !defined(HAVE_ERR) 5433955d011SMarcel Moolenaar void 5443955d011SMarcel Moolenaar err(int eval, const char *fmt, ...) 5453955d011SMarcel Moolenaar { 5463955d011SMarcel Moolenaar va_list ap; 5473955d011SMarcel Moolenaar 5483955d011SMarcel Moolenaar va_start(ap, fmt); 5493955d011SMarcel Moolenaar verr(eval, fmt, ap); 5503955d011SMarcel Moolenaar va_end(ap); 5513955d011SMarcel Moolenaar } 5523955d011SMarcel Moolenaar #endif 5533955d011SMarcel Moolenaar 5543955d011SMarcel Moolenaar #if !defined(HAVE_ERRX) 5553955d011SMarcel Moolenaar void 5563955d011SMarcel Moolenaar errx(int eval, const char *fmt, ...) 5573955d011SMarcel Moolenaar { 5583955d011SMarcel Moolenaar va_list ap; 5593955d011SMarcel Moolenaar 5603955d011SMarcel Moolenaar va_start(ap, fmt); 5613955d011SMarcel Moolenaar verrx(eval, fmt, ap); 5623955d011SMarcel Moolenaar va_end(ap); 5633955d011SMarcel Moolenaar } 5643955d011SMarcel Moolenaar #endif 5653955d011SMarcel Moolenaar 5663955d011SMarcel Moolenaar #if !defined(HAVE_WARN) 5673955d011SMarcel Moolenaar void 5683955d011SMarcel Moolenaar warn(const char *fmt, ...) 5693955d011SMarcel Moolenaar { 5703955d011SMarcel Moolenaar va_list ap; 5713955d011SMarcel Moolenaar 5723955d011SMarcel Moolenaar va_start(ap, fmt); 5733955d011SMarcel Moolenaar vwarn(fmt, ap); 5743955d011SMarcel Moolenaar va_end(ap); 5753955d011SMarcel Moolenaar } 5763955d011SMarcel Moolenaar #endif 5773955d011SMarcel Moolenaar 5783955d011SMarcel Moolenaar #if !defined(HAVE_WARNX) 5793955d011SMarcel Moolenaar void 5803955d011SMarcel Moolenaar warnx(const char *fmt, ...) 5813955d011SMarcel Moolenaar { 5823955d011SMarcel Moolenaar va_list ap; 5833955d011SMarcel Moolenaar 5843955d011SMarcel Moolenaar va_start(ap, fmt); 5853955d011SMarcel Moolenaar vwarnx(fmt, ap); 5863955d011SMarcel Moolenaar va_end(ap); 5873955d011SMarcel Moolenaar } 5883955d011SMarcel Moolenaar #endif 589