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