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