/* $NetBSD: util.c,v 1.25 2000/05/04 18:29:53 drochner Exp $ */ /* * Missing stuff from OS's */ #ifdef MAKE_BOOTSTRAP static char rcsid[] = "$NetBSD: util.c,v 1.25 2000/05/04 18:29:53 drochner Exp $"; #else #include #ifndef lint __RCSID("$NetBSD: util.c,v 1.25 2000/05/04 18:29:53 drochner Exp $"); #endif #endif #include #include #include "make.h" #include #ifndef __STDC__ # ifndef const # define const # endif #endif #ifdef sun extern int errno, sys_nerr; extern char *sys_errlist[]; char * strerror(e) int e; { static char buf[100]; if (e < 0 || e >= sys_nerr) { snprintf(buf, sizeof(buf), "Unknown error %d", e); return buf; } else return sys_errlist[e]; } #endif #ifdef ultrix #include /* strdup * * Make a duplicate of a string. * For systems which lack this function. */ char * strdup(str) const char *str; { size_t len; char *p; if (str == NULL) return NULL; len = strlen(str) + 1; p = emalloc(len); return memcpy(p, str, len); } #endif #if defined(sun) || defined(__hpux) || defined(__sgi) int setenv(name, value, dum) const char *name; const char *value; int dum; { register char *p; int len = strlen(name) + strlen(value) + 2; /* = \0 */ char *ptr = (char*) emalloc(len); (void) dum; if (ptr == NULL) return -1; p = ptr; while (*name) *p++ = *name++; *p++ = '='; while (*value) *p++ = *value++; *p = '\0'; len = putenv(ptr); /* free(ptr); */ return len; } #endif #ifdef __hpux #include #include #include #include #include #include #include #include #include #include int killpg(pid, sig) int pid, sig; { return kill(-pid, sig); } void srandom(seed) long seed; { srand48(seed); } long random() { return lrand48(); } /* turn into bsd signals */ void (* signal(s, a)) __P((int)) int s; void (*a) __P((int)); { struct sigvec osv, sv; (void) sigvector(s, (struct sigvec *) 0, &osv); sv = osv; sv.sv_handler = a; #ifdef SV_BSDSIG sv.sv_flags = SV_BSDSIG; #endif if (sigvector(s, &sv, (struct sigvec *) 0) == -1) return (BADSIG); return (osv.sv_handler); } #if !defined(BSD) && !defined(d_fileno) # define d_fileno d_ino #endif #ifndef DEV_DEV_COMPARE # define DEV_DEV_COMPARE(a, b) ((a) == (b)) #endif #define ISDOT(c) ((c)[0] == '.' && (((c)[1] == '\0') || ((c)[1] == '/'))) #define ISDOTDOT(c) ((c)[0] == '.' && ISDOT(&((c)[1]))) /* strrcpy(): * Like strcpy, going backwards and returning the new pointer */ static char * strrcpy(ptr, str) register char *ptr, *str; { register int len = strlen(str); while (len) *--ptr = str[--len]; return (ptr); } /* end strrcpy */ char * getwd(pathname) char *pathname; { DIR *dp; struct dirent *d; extern int errno; struct stat st_root, st_cur, st_next, st_dotdot; char pathbuf[MAXPATHLEN], nextpathbuf[MAXPATHLEN * 2]; char *pathptr, *nextpathptr, *cur_name_add; /* find the inode of root */ if (stat("/", &st_root) == -1) { (void) snprintf(pathname, sizeof(pathname), "getwd: Cannot stat \"/\" (%s)", strerror(errno)); return (NULL); } pathbuf[MAXPATHLEN - 1] = '\0'; pathptr = &pathbuf[MAXPATHLEN - 1]; nextpathbuf[MAXPATHLEN - 1] = '\0'; cur_name_add = nextpathptr = &nextpathbuf[MAXPATHLEN - 1]; /* find the inode of the current directory */ if (lstat(".", &st_cur) == -1) { (void) snprintf(pathname, sizeof(pathname), "getwd: Cannot stat \".\" (%s)", strerror(errno)); return (NULL); } nextpathptr = strrcpy(nextpathptr, "../"); /* Descend to root */ for (;;) { /* look if we found root yet */ if (st_cur.st_ino == st_root.st_ino && DEV_DEV_COMPARE(st_cur.st_dev, st_root.st_dev)) { (void) strcpy(pathname, *pathptr != '/' ? "/" : pathptr); return (pathname); } /* open the parent directory */ if (stat(nextpathptr, &st_dotdot) == -1) { (void) snprintf(pathname, sizeof(pathname), "getwd: Cannot stat directory \"%s\" (%s)", nextpathptr, strerror(errno)); return (NULL); } if ((dp = opendir(nextpathptr)) == NULL) { (void) snprintf(pathname, sizeof(pathname), "getwd: Cannot open directory \"%s\" (%s)", nextpathptr, strerror(errno)); return (NULL); } /* look in the parent for the entry with the same inode */ if (DEV_DEV_COMPARE(st_dotdot.st_dev, st_cur.st_dev)) { /* Parent has same device. No need to stat every member */ for (d = readdir(dp); d != NULL; d = readdir(dp)) if (d->d_fileno == st_cur.st_ino) break; } else { /* * Parent has a different device. This is a mount point so we * need to stat every member */ for (d = readdir(dp); d != NULL; d = readdir(dp)) { if (ISDOT(d->d_name) || ISDOTDOT(d->d_name)) continue; (void) strcpy(cur_name_add, d->d_name); if (lstat(nextpathptr, &st_next) == -1) { (void) snprintf(pathname, sizeof(pathname), "getwd: Cannot stat \"%s\" (%s)", d->d_name, strerror(errno)); (void) closedir(dp); return (NULL); } /* check if we found it yet */ if (st_next.st_ino == st_cur.st_ino && DEV_DEV_COMPARE(st_next.st_dev, st_cur.st_dev)) break; } } if (d == NULL) { (void) snprintf(pathname, sizeof(pathname), "getwd: Cannot find \".\" in \"..\""); (void) closedir(dp); return (NULL); } st_cur = st_dotdot; pathptr = strrcpy(pathptr, d->d_name); pathptr = strrcpy(pathptr, "/"); nextpathptr = strrcpy(nextpathptr, "../"); (void) closedir(dp); *cur_name_add = '\0'; } } /* end getwd */ char *sys_siglist[] = { "Signal 0", "Hangup", /* SIGHUP */ "Interrupt", /* SIGINT */ "Quit", /* SIGQUIT */ "Illegal instruction", /* SIGILL */ "Trace/BPT trap", /* SIGTRAP */ "IOT trap", /* SIGIOT */ "EMT trap", /* SIGEMT */ "Floating point exception", /* SIGFPE */ "Killed", /* SIGKILL */ "Bus error", /* SIGBUS */ "Segmentation fault", /* SIGSEGV */ "Bad system call", /* SIGSYS */ "Broken pipe", /* SIGPIPE */ "Alarm clock", /* SIGALRM */ "Terminated", /* SIGTERM */ "User defined signal 1", /* SIGUSR1 */ "User defined signal 2", /* SIGUSR2 */ "Child exited", /* SIGCLD */ "Power-fail restart", /* SIGPWR */ "Virtual timer expired", /* SIGVTALRM */ "Profiling timer expired", /* SIGPROF */ "I/O possible", /* SIGIO */ "Window size changes", /* SIGWINDOW */ "Stopped (signal)", /* SIGSTOP */ "Stopped", /* SIGTSTP */ "Continued", /* SIGCONT */ "Stopped (tty input)", /* SIGTTIN */ "Stopped (tty output)", /* SIGTTOU */ "Urgent I/O condition", /* SIGURG */ "Remote lock lost (NFS)", /* SIGLOST */ "Signal 31", /* reserved */ "DIL signal" /* SIGDIL */ }; int utimes(file, tvp) char *file; struct timeval tvp[2]; { struct utimbuf t; t.actime = tvp[0].tv_sec; t.modtime = tvp[1].tv_sec; return(utime(file, &t)); } #endif /* __hpux */ #if defined(sun) && defined(__svr4__) #include /* turn into bsd signals */ void (* signal(s, a)) __P((int)) int s; void (*a) __P((int)); { struct sigaction sa, osa; sa.sa_handler = a; sigemptyset(&sa.sa_mask); sa.sa_flags = SA_RESTART; if (sigaction(s, &sa, &osa) == -1) return SIG_ERR; else return osa.sa_handler; } #endif #if !defined(BSD4_4) && !defined(SUNOS_5_7) && !defined(__linux__) #ifdef __STDC__ #include #else #include #endif #if !defined(__osf__) #ifdef _IOSTRG #define STRFLAG (_IOSTRG|_IOWRT) /* no _IOWRT: avoid stdio bug */ #else #if 0 #define STRFLAG (_IOREAD) /* XXX: Assume svr4 stdio */ #endif #endif /* _IOSTRG */ #endif /* __osf__ */ int vsnprintf(s, n, fmt, args) char *s; size_t n; const char *fmt; va_list args; { #ifdef STRFLAG FILE fakebuf; fakebuf._flag = STRFLAG; /* * Some os's are char * _ptr, others are unsigned char *_ptr... * We cast to void * to make everyone happy. */ fakebuf._ptr = (void *) s; fakebuf._cnt = n-1; fakebuf._file = -1; _doprnt(fmt, args, &fakebuf); fakebuf._cnt++; putc('\0', &fakebuf); if (fakebuf._cnt<0) fakebuf._cnt = 0; return (n-fakebuf._cnt-1); #else (void) vsprintf(s, fmt, args); return strlen(s); #endif } int #ifdef __STDC__ snprintf(char *s, size_t n, const char *fmt, ...) #else snprintf(va_alist) va_dcl #endif { va_list ap; int rv; #ifdef __STDC__ va_start(ap, fmt); #else char *s; size_t n; const char *fmt; va_start(ap); s = va_arg(ap, char *); n = va_arg(ap, size_t); fmt = va_arg(ap, const char *); #endif rv = vsnprintf(s, n, fmt, ap); va_end(ap); return rv; } #if !defined(__SVR4) && !defined(__linux__) && !defined(ultrix) \ && !defined(__sgi) && !defined(__osf__) int strftime(buf, len, fmt, tm) char *buf; size_t len; const char *fmt; const struct tm *tm; { static char months[][4] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; size_t s; char *b = buf; while (*fmt) { if (len == 0) return buf - b; if (*fmt != '%') { *buf++ = *fmt++; len--; continue; } switch (*fmt++) { case '%': *buf++ = '%'; len--; if (len == 0) return buf - b; /*FALLTHROUGH*/ case '\0': *buf = '%'; s = 1; break; case 'k': s = snprintf(buf, len, "%d", tm->tm_hour); break; case 'M': s = snprintf(buf, len, "%02d", tm->tm_min); break; case 'S': s = snprintf(buf, len, "%02d", tm->tm_sec); break; case 'b': if (tm->tm_mon >= 12) return buf - b; s = snprintf(buf, len, "%s", months[tm->tm_mon]); break; case 'd': s = snprintf(buf, len, "%s", tm->tm_mday); break; case 'Y': s = snprintf(buf, len, "%s", 1900 + tm->tm_year); break; default: s = snprintf(buf, len, "Unsupported format %c", fmt[-1]); break; } buf += s; len -= s; } } #endif #endif