Annotation of src/usr.bin/make/util.c, Revision 1.16
1.14 espie 1: /* $OpenPackages$ */
1.16 ! espie 2: /* $OpenBSD: util.c,v 1.10 1998/12/20 23:38:11 deraadt Exp $ */
1.6 millert 3: /* $NetBSD: util.c,v 1.10 1996/12/31 17:56:04 christos Exp $ */
1.1 deraadt 4:
5: /*
1.16 ! espie 6: * Copyright (c) 2001 Marc Espie.
! 7: *
! 8: * Redistribution and use in source and binary forms, with or without
! 9: * modification, are permitted provided that the following conditions
! 10: * are met:
! 11: * 1. Redistributions of source code must retain the above copyright
! 12: * notice, this list of conditions and the following disclaimer.
! 13: * 2. Redistributions in binary form must reproduce the above copyright
! 14: * notice, this list of conditions and the following disclaimer in the
! 15: * documentation and/or other materials provided with the distribution.
! 16: *
! 17: * THIS SOFTWARE IS PROVIDED BY THE OPENBSD PROJECT AND CONTRIBUTORS
! 18: * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
! 19: * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
! 20: * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OPENBSD
! 21: * PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
! 22: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
! 23: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
! 24: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
! 25: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
! 26: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
! 27: * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
! 28: */
! 29: /*
1.1 deraadt 30: * Missing stuff from OS's
31: */
32:
1.16 ! espie 33: #include <sys/param.h>
1.1 deraadt 34: #include <stdio.h>
1.16 ! espie 35: #include "config.h"
! 36: #include "defines.h"
1.13 espie 37:
1.7 mickey 38: #ifndef __STDC__
1.1 deraadt 39: # ifndef const
40: # define const
41: # endif
42: #endif
43:
44: #ifdef sun
45:
46:
47:
48: extern int errno, sys_nerr;
49: extern char *sys_errlist[];
50:
51: char *
1.5 millert 52: strerror(e)
53: int e;
1.1 deraadt 54: {
55: static char buf[100];
56: if (e < 0 || e >= sys_nerr) {
57: sprintf(buf, "Unknown error %d", e);
58: return buf;
59: }
60: else
61: return sys_errlist[e];
62: }
63: #endif
64:
1.4 briggs 65: #ifdef ultrix
66: #include <string.h>
67:
68: /* strdup
69: *
70: * Make a duplicate of a string.
71: * For systems which lack this function.
72: */
73: char *
74: strdup(str)
75: const char *str;
76: {
77: size_t len;
1.5 millert 78: char *p;
1.4 briggs 79:
80: if (str == NULL)
81: return NULL;
82: len = strlen(str) + 1;
83: if ((p = malloc(len)) == NULL)
84: return NULL;
85:
86: return memcpy(p, str, len);
87: }
88:
89: #endif
90:
91: #if defined(sun) || defined(__hpux) || defined(__sgi)
1.1 deraadt 92:
93: int
94: setenv(name, value, dum)
1.5 millert 95: const char *name;
1.1 deraadt 96: const char *value;
97: int dum;
98: {
1.14 espie 99: char *p;
1.1 deraadt 100: int len = strlen(name) + strlen(value) + 2; /* = \0 */
1.14 espie 101: char *ptr = (char*)malloc(len);
1.1 deraadt 102:
103: if (ptr == NULL)
104: return -1;
1.5 millert 105:
1.1 deraadt 106: p = ptr;
107:
1.5 millert 108: while (*name)
1.1 deraadt 109: *p++ = *name++;
110:
111: *p++ = '=';
112:
1.5 millert 113: while (*value)
1.1 deraadt 114: *p++ = *value++;
115:
116: *p = '\0';
117:
118: len = putenv(ptr);
119: /* free(ptr); */
120: return len;
121: }
122: #endif
123:
124: #ifdef __hpux
125: #include <sys/types.h>
126: #include <sys/param.h>
127: #include <sys/syscall.h>
128: #include <sys/signal.h>
129: #include <sys/stat.h>
130: #include <stdio.h>
131: #include <dirent.h>
132: #include <sys/time.h>
133: #include <time.h>
134: #include <unistd.h>
135:
136:
137: int
138: killpg(pid, sig)
139: int pid, sig;
140: {
141: return kill(-pid, sig);
142: }
143:
144: void
145: srandom(seed)
146: long seed;
147: {
148: srand48(seed);
149: }
150:
151: long
152: random()
153: {
154: return lrand48();
155: }
156:
157: /* turn into bsd signals */
158: void (*
1.14 espie 159: signal(s, a))()
1.1 deraadt 160: int s;
161: void (*a)();
162: {
163: struct sigvec osv, sv;
164:
1.14 espie 165: (void)sigvector(s, (struct sigvec *)0, &osv);
1.1 deraadt 166: sv = osv;
167: sv.sv_handler = a;
168: #ifdef SV_BSDSIG
169: sv.sv_flags = SV_BSDSIG;
170: #endif
171:
1.14 espie 172: if (sigvector(s, &sv, (struct sigvec *)0) == -1)
173: return SIG_ERR;
174: return osv.sv_handler;
1.1 deraadt 175: }
176:
177: #if !defined(BSD) && !defined(d_fileno)
178: # define d_fileno d_ino
179: #endif
180:
181: #ifndef DEV_DEV_COMPARE
182: # define DEV_DEV_COMPARE(a, b) ((a) == (b))
183: #endif
1.14 espie 184: #define ISDOT(c) ((c)[0] == '.' && ((c)[1] == '\0' || (c)[1] == '/'))
1.1 deraadt 185: #define ISDOTDOT(c) ((c)[0] == '.' && ISDOT(&((c)[1])))
186:
187:
188: /* strrcpy():
189: * Like strcpy, going backwards and returning the new pointer
190: */
191: static char *
192: strrcpy(ptr, str)
1.14 espie 193: char *ptr, *str;
1.1 deraadt 194: {
1.14 espie 195: size_t len = strlen(str);
1.1 deraadt 196:
197: while (len)
198: *--ptr = str[--len];
199:
1.14 espie 200: return ptr;
1.1 deraadt 201: } /* end strrcpy */
202:
203:
204: char *
205: getwd(pathname)
206: char *pathname;
207: {
208: DIR *dp;
209: struct dirent *d;
210: extern int errno;
211:
212: struct stat st_root, st_cur, st_next, st_dotdot;
213: char pathbuf[MAXPATHLEN], nextpathbuf[MAXPATHLEN * 2];
214: char *pathptr, *nextpathptr, *cur_name_add;
215:
216: /* find the inode of root */
217: if (stat("/", &st_root) == -1) {
1.14 espie 218: (void)sprintf(pathname,
1.1 deraadt 219: "getwd: Cannot stat \"/\" (%s)", strerror(errno));
1.14 espie 220: return NULL;
1.1 deraadt 221: }
222: pathbuf[MAXPATHLEN - 1] = '\0';
223: pathptr = &pathbuf[MAXPATHLEN - 1];
224: nextpathbuf[MAXPATHLEN - 1] = '\0';
225: cur_name_add = nextpathptr = &nextpathbuf[MAXPATHLEN - 1];
226:
227: /* find the inode of the current directory */
228: if (lstat(".", &st_cur) == -1) {
1.14 espie 229: (void)sprintf(pathname,
1.1 deraadt 230: "getwd: Cannot stat \".\" (%s)", strerror(errno));
1.14 espie 231: return NULL;
1.1 deraadt 232: }
233: nextpathptr = strrcpy(nextpathptr, "../");
234:
235: /* Descend to root */
236: for (;;) {
237:
238: /* look if we found root yet */
239: if (st_cur.st_ino == st_root.st_ino &&
240: DEV_DEV_COMPARE(st_cur.st_dev, st_root.st_dev)) {
1.14 espie 241: (void)strcpy(pathname, *pathptr != '/' ? "/" : pathptr);
242: return pathname;
1.1 deraadt 243: }
244:
245: /* open the parent directory */
246: if (stat(nextpathptr, &st_dotdot) == -1) {
1.14 espie 247: (void)sprintf(pathname,
1.1 deraadt 248: "getwd: Cannot stat directory \"%s\" (%s)",
249: nextpathptr, strerror(errno));
1.14 espie 250: return NULL;
1.1 deraadt 251: }
252: if ((dp = opendir(nextpathptr)) == NULL) {
1.14 espie 253: (void)sprintf(pathname,
1.1 deraadt 254: "getwd: Cannot open directory \"%s\" (%s)",
255: nextpathptr, strerror(errno));
1.14 espie 256: return NULL;
1.1 deraadt 257: }
258:
259: /* look in the parent for the entry with the same inode */
260: if (DEV_DEV_COMPARE(st_dotdot.st_dev, st_cur.st_dev)) {
261: /* Parent has same device. No need to stat every member */
1.5 millert 262: for (d = readdir(dp); d != NULL; d = readdir(dp))
1.1 deraadt 263: if (d->d_fileno == st_cur.st_ino)
264: break;
265: }
266: else {
1.5 millert 267: /*
268: * Parent has a different device. This is a mount point so we
269: * need to stat every member
1.1 deraadt 270: */
271: for (d = readdir(dp); d != NULL; d = readdir(dp)) {
272: if (ISDOT(d->d_name) || ISDOTDOT(d->d_name))
273: continue;
1.14 espie 274: (void)strcpy(cur_name_add, d->d_name);
1.1 deraadt 275: if (lstat(nextpathptr, &st_next) == -1) {
1.14 espie 276: (void)sprintf(pathname, "getwd: Cannot stat \"%s\" (%s)",
1.1 deraadt 277: d->d_name, strerror(errno));
1.14 espie 278: (void)closedir(dp);
279: return NULL;
1.1 deraadt 280: }
281: /* check if we found it yet */
282: if (st_next.st_ino == st_cur.st_ino &&
1.5 millert 283: DEV_DEV_COMPARE(st_next.st_dev, st_cur.st_dev))
1.1 deraadt 284: break;
285: }
286: }
287: if (d == NULL) {
1.14 espie 288: (void)sprintf(pathname, "getwd: Cannot find \".\" in \"..\"");
289: (void)closedir(dp);
290: return NULL;
1.1 deraadt 291: }
292: st_cur = st_dotdot;
293: pathptr = strrcpy(pathptr, d->d_name);
294: pathptr = strrcpy(pathptr, "/");
295: nextpathptr = strrcpy(nextpathptr, "../");
1.14 espie 296: (void)closedir(dp);
1.1 deraadt 297: *cur_name_add = '\0';
298: }
299: } /* end getwd */
300:
301:
1.14 espie 302: char *sys_siglist[] = {
303: "Signal 0",
304: "Hangup", /* SIGHUP */
305: "Interrupt", /* SIGINT */
306: "Quit", /* SIGQUIT */
307: "Illegal instruction", /* SIGILL */
308: "Trace/BPT trap", /* SIGTRAP */
309: "IOT trap", /* SIGIOT */
310: "EMT trap", /* SIGEMT */
311: "Floating point exception", /* SIGFPE */
312: "Killed", /* SIGKILL */
313: "Bus error", /* SIGBUS */
314: "Segmentation fault", /* SIGSEGV */
315: "Bad system call", /* SIGSYS */
316: "Broken pipe", /* SIGPIPE */
317: "Alarm clock", /* SIGALRM */
318: "Terminated", /* SIGTERM */
319: "User defined signal 1", /* SIGUSR1 */
320: "User defined signal 2", /* SIGUSR2 */
321: "Child exited", /* SIGCLD */
322: "Power-fail restart", /* SIGPWR */
323: "Virtual timer expired", /* SIGVTALRM */
324: "Profiling timer expired", /* SIGPROF */
325: "I/O possible", /* SIGIO */
326: "Window size changes", /* SIGWINDOW */
327: "Stopped (signal)", /* SIGSTOP */
328: "Stopped", /* SIGTSTP */
329: "Continued", /* SIGCONT */
330: "Stopped (tty input)", /* SIGTTIN */
331: "Stopped (tty output)", /* SIGTTOU */
332: "Urgent I/O condition", /* SIGURG */
333: "Remote lock lost (NFS)", /* SIGLOST */
334: "Signal 31", /* reserved */
335: "DIL signal" /* SIGDIL */
1.1 deraadt 336: };
337:
338: int
339: utimes(file, tvp)
340: char *file;
341: struct timeval tvp[2];
342: {
343: struct utimbuf t;
344:
345: t.actime = tvp[0].tv_sec;
346: t.modtime = tvp[1].tv_sec;
1.14 espie 347: return utime(file, &t);
1.1 deraadt 348: }
349:
350:
351: #endif /* __hpux */
1.2 deraadt 352:
353: #if defined(sun) && defined(__svr4__)
354: #include <signal.h>
355:
356: /* turn into bsd signals */
357: void (*
1.14 espie 358: signal(s, a))()
1.2 deraadt 359: int s;
360: void (*a)();
361: {
362: struct sigaction sa, osa;
363:
1.8 deraadt 364: memset(&sa, 0, sizeof sa);
1.2 deraadt 365: sa.sa_handler = a;
366: sigemptyset(&sa.sa_mask);
367: sa.sa_flags = SA_RESTART;
368:
369: if (sigaction(s, &sa, &osa) == -1)
370: return SIG_ERR;
371: else
372: return osa.sa_handler;
373: }
374:
1.6 millert 375: #endif
376:
1.16 ! espie 377: #ifndef BSD4_4
1.6 millert 378: #ifdef __STDC__
379: #include <stdarg.h>
380: #else
381: #include <varargs.h>
382: #endif
383:
384: #ifdef _IOSTRG
1.14 espie 385: #define STRFLAG (_IOSTRG|_IOWRT) /* no _IOWRT: avoid stdio bug */
1.6 millert 386: #else
1.14 espie 387: #define STRFLAG (_IOREAD) /* XXX: Assume svr4 stdio */
1.6 millert 388: #endif
389:
390: int
391: vsnprintf(s, n, fmt, args)
392: char *s;
393: size_t n;
394: const char *fmt;
395: va_list args;
396: {
397: FILE fakebuf;
398:
399: fakebuf._flag = STRFLAG;
400: /*
401: * Some os's are char * _ptr, others are unsigned char *_ptr...
402: * We cast to void * to make everyone happy.
403: */
1.14 espie 404: fakebuf._ptr = (void *)s;
1.6 millert 405: fakebuf._cnt = n-1;
406: fakebuf._file = -1;
407: _doprnt(fmt, args, &fakebuf);
408: fakebuf._cnt++;
409: putc('\0', &fakebuf);
410: if (fakebuf._cnt<0)
411: fakebuf._cnt = 0;
1.14 espie 412: return n-fakebuf._cnt-1;
1.6 millert 413: }
414:
415: int
416: #ifdef __STDC__
417: snprintf(char *s, size_t n, const char *fmt, ...)
418: #else
419: snprintf(va_alist)
420: va_dcl
421: #endif
422: {
423: va_list ap;
424: int rv;
425: #ifdef __STDC__
426: va_start(ap, fmt);
427: #else
428: char *s;
429: size_t n;
430: const char *fmt;
431:
432: va_start(ap);
433:
434: s = va_arg(ap, char *);
435: n = va_arg(ap, size_t);
436: fmt = va_arg(ap, const char *);
437: #endif
438: rv = vsnprintf(s, n, fmt, ap);
439: va_end(ap);
440: return rv;
1.11 espie 441: }
442: #endif
443: #ifdef NEED_STRSTR
444: char *
445: strstr(string, substring)
446: const char *string; /* String to search. */
447: const char *substring; /* Substring to find in string */
448: {
449: const char *a, *b;
450:
451: /*
452: * First scan quickly through the two strings looking for a single-
453: * character match. When it's found, then compare the rest of the
454: * substring.
455: */
456:
457: for (b = substring; *string != 0; string += 1) {
458: if (*string != *b)
459: continue;
460: a = string;
461: for (;;) {
462: if (*b == 0)
463: return (char *)string;
464: if (*a++ != *b++)
465: break;
466: }
467: b = substring;
468: }
469: return NULL;
1.12 espie 470: }
471: #endif
472:
473: #ifdef NEED_FGETLN
474: char *
475: fgetln(stream, len)
476: FILE *stream;
477: size_t *len;
478: {
479: static char *buffer = NULL;
480: static size_t buflen = 0;
481:
482: if (buflen == 0) {
1.14 espie 483: buflen = 512;
1.12 espie 484: buffer = emalloc(buflen+1);
485: }
486: if (fgets(buffer, buflen+1, stream) == NULL)
487: return NULL;
488: *len = strlen(buffer);
489: while (*len == buflen && buffer[*len-1] != '\n') {
490: buffer = erealloc(buffer, 2*buflen + 1);
491: if (fgets(buffer + buflen, buflen + 1, stream) == NULL)
492: return NULL;
493: *len += strlen(buffer + buflen);
494: buflen *= 2;
495: }
496: return buffer;
1.6 millert 497: }
1.2 deraadt 498: #endif