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