Annotation of src/usr.bin/make/util.c, Revision 1.25
1.25 ! espie 1: /* $OpenBSD: util.c,v 1.24 2010/07/19 19:30:38 espie Exp $ */
1.6 millert 2: /* $NetBSD: util.c,v 1.10 1996/12/31 17:56:04 christos Exp $ */
1.1 deraadt 3:
4: /*
1.16 espie 5: * Copyright (c) 2001 Marc Espie.
6: *
7: * Redistribution and use in source and binary forms, with or without
8: * modification, are permitted provided that the following conditions
9: * are met:
10: * 1. Redistributions of source code must retain the above copyright
11: * notice, this list of conditions and the following disclaimer.
12: * 2. Redistributions in binary form must reproduce the above copyright
13: * notice, this list of conditions and the following disclaimer in the
14: * documentation and/or other materials provided with the distribution.
15: *
16: * THIS SOFTWARE IS PROVIDED BY THE OPENBSD PROJECT AND CONTRIBUTORS
17: * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18: * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19: * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OPENBSD
20: * PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26: * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27: */
28: /*
1.1 deraadt 29: * Missing stuff from OS's
30: */
31:
1.16 espie 32: #include <sys/param.h>
1.1 deraadt 33: #include <stdio.h>
1.16 espie 34: #include "config.h"
35: #include "defines.h"
1.13 espie 36:
1.1 deraadt 37: #ifdef sun
38:
39: extern int errno, sys_nerr;
40: extern char *sys_errlist[];
41:
42: char *
1.5 millert 43: strerror(e)
44: int e;
1.1 deraadt 45: {
46: static char buf[100];
47: if (e < 0 || e >= sys_nerr) {
1.18 deraadt 48: snprintf(buf, sizeof buf, "Unknown error %d", e);
1.1 deraadt 49: return buf;
50: }
51: else
52: return sys_errlist[e];
53: }
54: #endif
55:
1.4 briggs 56: #ifdef ultrix
57: #include <string.h>
58:
59: /* strdup
60: *
61: * Make a duplicate of a string.
62: * For systems which lack this function.
63: */
64: char *
65: strdup(str)
66: const char *str;
67: {
68: size_t len;
1.5 millert 69: char *p;
1.4 briggs 70:
71: if (str == NULL)
72: return NULL;
73: len = strlen(str) + 1;
74: if ((p = malloc(len)) == NULL)
75: return NULL;
76:
77: return memcpy(p, str, len);
78: }
79:
80: #endif
81:
82: #if defined(sun) || defined(__hpux) || defined(__sgi)
1.1 deraadt 83:
84: int
85: setenv(name, value, dum)
1.5 millert 86: const char *name;
1.1 deraadt 87: const char *value;
88: int dum;
89: {
1.14 espie 90: char *p;
1.1 deraadt 91: int len = strlen(name) + strlen(value) + 2; /* = \0 */
1.14 espie 92: char *ptr = (char*)malloc(len);
1.1 deraadt 93:
94: if (ptr == NULL)
95: return -1;
1.5 millert 96:
1.1 deraadt 97: p = ptr;
98:
1.5 millert 99: while (*name)
1.1 deraadt 100: *p++ = *name++;
101:
102: *p++ = '=';
103:
1.5 millert 104: while (*value)
1.1 deraadt 105: *p++ = *value++;
106:
107: *p = '\0';
108:
109: len = putenv(ptr);
110: /* free(ptr); */
111: return len;
112: }
113: #endif
114:
115: #ifdef __hpux
116: #include <sys/types.h>
117: #include <sys/param.h>
118: #include <sys/syscall.h>
119: #include <sys/signal.h>
120: #include <sys/stat.h>
121: #include <stdio.h>
122: #include <dirent.h>
123: #include <sys/time.h>
124: #include <time.h>
125: #include <unistd.h>
126:
127:
128: int
129: killpg(pid, sig)
130: int pid, sig;
131: {
132: return kill(-pid, sig);
133: }
134:
135: void
136: srandom(seed)
137: long seed;
138: {
139: srand48(seed);
140: }
141:
142: long
143: random()
144: {
145: return lrand48();
146: }
147:
148: /* turn into bsd signals */
149: void (*
1.14 espie 150: signal(s, a))()
1.1 deraadt 151: int s;
152: void (*a)();
153: {
154: struct sigvec osv, sv;
155:
1.14 espie 156: (void)sigvector(s, (struct sigvec *)0, &osv);
1.1 deraadt 157: sv = osv;
158: sv.sv_handler = a;
159: #ifdef SV_BSDSIG
160: sv.sv_flags = SV_BSDSIG;
161: #endif
162:
1.14 espie 163: if (sigvector(s, &sv, (struct sigvec *)0) == -1)
164: return SIG_ERR;
165: return osv.sv_handler;
1.1 deraadt 166: }
167:
168: #if !defined(BSD) && !defined(d_fileno)
169: # define d_fileno d_ino
170: #endif
171:
172: #ifndef DEV_DEV_COMPARE
173: # define DEV_DEV_COMPARE(a, b) ((a) == (b))
174: #endif
1.14 espie 175: #define ISDOT(c) ((c)[0] == '.' && ((c)[1] == '\0' || (c)[1] == '/'))
1.1 deraadt 176: #define ISDOTDOT(c) ((c)[0] == '.' && ISDOT(&((c)[1])))
177:
178:
179: /* strrcpy():
180: * Like strcpy, going backwards and returning the new pointer
181: */
182: static char *
183: strrcpy(ptr, str)
1.14 espie 184: char *ptr, *str;
1.1 deraadt 185: {
1.14 espie 186: size_t len = strlen(str);
1.1 deraadt 187:
188: while (len)
189: *--ptr = str[--len];
190:
1.14 espie 191: return ptr;
1.1 deraadt 192: } /* end strrcpy */
193:
194:
195: char *
196: getwd(pathname)
197: char *pathname;
198: {
199: DIR *dp;
200: struct dirent *d;
201: extern int errno;
202:
203: struct stat st_root, st_cur, st_next, st_dotdot;
204: char pathbuf[MAXPATHLEN], nextpathbuf[MAXPATHLEN * 2];
205: char *pathptr, *nextpathptr, *cur_name_add;
206:
207: /* find the inode of root */
208: if (stat("/", &st_root) == -1) {
1.23 espie 209: (void)snprintf(pathname, MAXPATHLEN,
1.18 deraadt 210: "getwd: Cannot stat \"/\" (%s)", strerror(errno));
1.14 espie 211: return NULL;
1.1 deraadt 212: }
213: pathbuf[MAXPATHLEN - 1] = '\0';
214: pathptr = &pathbuf[MAXPATHLEN - 1];
215: nextpathbuf[MAXPATHLEN - 1] = '\0';
216: cur_name_add = nextpathptr = &nextpathbuf[MAXPATHLEN - 1];
217:
218: /* find the inode of the current directory */
219: if (lstat(".", &st_cur) == -1) {
1.19 espie 220: (void)snprintf(pathname, MAXPATHLEN,
1.18 deraadt 221: "getwd: Cannot stat \".\" (%s)", strerror(errno));
1.14 espie 222: return NULL;
1.1 deraadt 223: }
224: nextpathptr = strrcpy(nextpathptr, "../");
225:
226: /* Descend to root */
227: for (;;) {
228:
229: /* look if we found root yet */
230: if (st_cur.st_ino == st_root.st_ino &&
231: DEV_DEV_COMPARE(st_cur.st_dev, st_root.st_dev)) {
1.19 espie 232: (void)strlcpy(pathname, *pathptr != '/' ? "/" : pathptr, MAXPATHLEN);
1.14 espie 233: return pathname;
1.1 deraadt 234: }
235:
236: /* open the parent directory */
237: if (stat(nextpathptr, &st_dotdot) == -1) {
1.19 espie 238: (void)snprintf(pathname, MAXPATHLEN,
1.18 deraadt 239: "getwd: Cannot stat directory \"%s\" (%s)",
240: nextpathptr, strerror(errno));
1.14 espie 241: return NULL;
1.1 deraadt 242: }
243: if ((dp = opendir(nextpathptr)) == NULL) {
1.19 espie 244: (void)snprintf(pathname, MAXPATHLEN,
1.18 deraadt 245: "getwd: Cannot open directory \"%s\" (%s)",
246: nextpathptr, strerror(errno));
1.14 espie 247: return NULL;
1.1 deraadt 248: }
249:
250: /* look in the parent for the entry with the same inode */
251: if (DEV_DEV_COMPARE(st_dotdot.st_dev, st_cur.st_dev)) {
252: /* Parent has same device. No need to stat every member */
1.5 millert 253: for (d = readdir(dp); d != NULL; d = readdir(dp))
1.1 deraadt 254: if (d->d_fileno == st_cur.st_ino)
255: break;
256: }
257: else {
1.5 millert 258: /*
259: * Parent has a different device. This is a mount point so we
260: * need to stat every member
1.1 deraadt 261: */
262: for (d = readdir(dp); d != NULL; d = readdir(dp)) {
263: if (ISDOT(d->d_name) || ISDOTDOT(d->d_name))
264: continue;
1.23 espie 265: (void)strlcpy(cur_name_add, d->d_name,
1.21 millert 266: sizeof(nextpathbuf) MAXPATHLEN - (MAXPATHLEN - 1));
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:
1.22 espie 431: for (b = substring; *string != 0; string++) {
1.11 espie 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