Annotation of src/usr.bin/make/util.c, Revision 1.17
1.14 espie 1: /* $OpenPackages$ */
1.17 ! millert 2: /* $OpenBSD: util.c,v 1.16 2001/05/23 12:34:51 espie 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) {
49: sprintf(buf, "Unknown error %d", e);
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.14 espie 210: (void)sprintf(pathname,
1.1 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.14 espie 221: (void)sprintf(pathname,
1.1 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.14 espie 233: (void)strcpy(pathname, *pathptr != '/' ? "/" : pathptr);
234: return pathname;
1.1 deraadt 235: }
236:
237: /* open the parent directory */
238: if (stat(nextpathptr, &st_dotdot) == -1) {
1.14 espie 239: (void)sprintf(pathname,
1.1 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.14 espie 245: (void)sprintf(pathname,
1.1 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.14 espie 268: (void)sprintf(pathname, "getwd: Cannot stat \"%s\" (%s)",
1.1 deraadt 269: d->d_name, strerror(errno));
1.14 espie 270: (void)closedir(dp);
271: return NULL;
1.1 deraadt 272: }
273: /* check if we found it yet */
274: if (st_next.st_ino == st_cur.st_ino &&
1.5 millert 275: DEV_DEV_COMPARE(st_next.st_dev, st_cur.st_dev))
1.1 deraadt 276: break;
277: }
278: }
279: if (d == NULL) {
1.14 espie 280: (void)sprintf(pathname, "getwd: Cannot find \".\" in \"..\"");
281: (void)closedir(dp);
282: return NULL;
1.1 deraadt 283: }
284: st_cur = st_dotdot;
285: pathptr = strrcpy(pathptr, d->d_name);
286: pathptr = strrcpy(pathptr, "/");
287: nextpathptr = strrcpy(nextpathptr, "../");
1.14 espie 288: (void)closedir(dp);
1.1 deraadt 289: *cur_name_add = '\0';
290: }
291: } /* end getwd */
292:
293:
1.14 espie 294: char *sys_siglist[] = {
295: "Signal 0",
296: "Hangup", /* SIGHUP */
297: "Interrupt", /* SIGINT */
298: "Quit", /* SIGQUIT */
299: "Illegal instruction", /* SIGILL */
300: "Trace/BPT trap", /* SIGTRAP */
301: "IOT trap", /* SIGIOT */
302: "EMT trap", /* SIGEMT */
303: "Floating point exception", /* SIGFPE */
304: "Killed", /* SIGKILL */
305: "Bus error", /* SIGBUS */
306: "Segmentation fault", /* SIGSEGV */
307: "Bad system call", /* SIGSYS */
308: "Broken pipe", /* SIGPIPE */
309: "Alarm clock", /* SIGALRM */
310: "Terminated", /* SIGTERM */
311: "User defined signal 1", /* SIGUSR1 */
312: "User defined signal 2", /* SIGUSR2 */
313: "Child exited", /* SIGCLD */
314: "Power-fail restart", /* SIGPWR */
315: "Virtual timer expired", /* SIGVTALRM */
316: "Profiling timer expired", /* SIGPROF */
317: "I/O possible", /* SIGIO */
318: "Window size changes", /* SIGWINDOW */
319: "Stopped (signal)", /* SIGSTOP */
320: "Stopped", /* SIGTSTP */
321: "Continued", /* SIGCONT */
322: "Stopped (tty input)", /* SIGTTIN */
323: "Stopped (tty output)", /* SIGTTOU */
324: "Urgent I/O condition", /* SIGURG */
325: "Remote lock lost (NFS)", /* SIGLOST */
326: "Signal 31", /* reserved */
327: "DIL signal" /* SIGDIL */
1.1 deraadt 328: };
329:
330: int
331: utimes(file, tvp)
332: char *file;
333: struct timeval tvp[2];
334: {
335: struct utimbuf t;
336:
337: t.actime = tvp[0].tv_sec;
338: t.modtime = tvp[1].tv_sec;
1.14 espie 339: return utime(file, &t);
1.1 deraadt 340: }
341:
342:
343: #endif /* __hpux */
1.2 deraadt 344:
345: #if defined(sun) && defined(__svr4__)
346: #include <signal.h>
347:
348: /* turn into bsd signals */
349: void (*
1.14 espie 350: signal(s, a))()
1.2 deraadt 351: int s;
352: void (*a)();
353: {
354: struct sigaction sa, osa;
355:
1.8 deraadt 356: memset(&sa, 0, sizeof sa);
1.2 deraadt 357: sa.sa_handler = a;
358: sigemptyset(&sa.sa_mask);
359: sa.sa_flags = SA_RESTART;
360:
361: if (sigaction(s, &sa, &osa) == -1)
362: return SIG_ERR;
363: else
364: return osa.sa_handler;
365: }
366:
1.6 millert 367: #endif
368:
1.16 espie 369: #ifndef BSD4_4
1.6 millert 370: #include <stdarg.h>
371:
372: #ifdef _IOSTRG
1.14 espie 373: #define STRFLAG (_IOSTRG|_IOWRT) /* no _IOWRT: avoid stdio bug */
1.6 millert 374: #else
1.14 espie 375: #define STRFLAG (_IOREAD) /* XXX: Assume svr4 stdio */
1.6 millert 376: #endif
377:
378: int
379: vsnprintf(s, n, fmt, args)
380: char *s;
381: size_t n;
382: const char *fmt;
383: va_list args;
384: {
385: FILE fakebuf;
386:
387: fakebuf._flag = STRFLAG;
388: /*
389: * Some os's are char * _ptr, others are unsigned char *_ptr...
390: * We cast to void * to make everyone happy.
391: */
1.14 espie 392: fakebuf._ptr = (void *)s;
1.6 millert 393: fakebuf._cnt = n-1;
394: fakebuf._file = -1;
395: _doprnt(fmt, args, &fakebuf);
396: fakebuf._cnt++;
397: putc('\0', &fakebuf);
398: if (fakebuf._cnt<0)
399: fakebuf._cnt = 0;
1.14 espie 400: return n-fakebuf._cnt-1;
1.6 millert 401: }
402:
403: int
404: snprintf(char *s, size_t n, const char *fmt, ...)
405: {
406: va_list ap;
407: int rv;
1.17 ! millert 408:
1.6 millert 409: va_start(ap, fmt);
410: rv = vsnprintf(s, n, fmt, ap);
411: va_end(ap);
412: return rv;
1.11 espie 413: }
414: #endif
415: #ifdef NEED_STRSTR
416: char *
417: strstr(string, substring)
418: const char *string; /* String to search. */
419: const char *substring; /* Substring to find in string */
420: {
421: const char *a, *b;
422:
423: /*
424: * First scan quickly through the two strings looking for a single-
425: * character match. When it's found, then compare the rest of the
426: * substring.
427: */
428:
429: for (b = substring; *string != 0; string += 1) {
430: if (*string != *b)
431: continue;
432: a = string;
433: for (;;) {
434: if (*b == 0)
435: return (char *)string;
436: if (*a++ != *b++)
437: break;
438: }
439: b = substring;
440: }
441: return NULL;
1.12 espie 442: }
443: #endif
444:
445: #ifdef NEED_FGETLN
446: char *
447: fgetln(stream, len)
448: FILE *stream;
449: size_t *len;
450: {
451: static char *buffer = NULL;
452: static size_t buflen = 0;
453:
454: if (buflen == 0) {
1.14 espie 455: buflen = 512;
1.12 espie 456: buffer = emalloc(buflen+1);
457: }
458: if (fgets(buffer, buflen+1, stream) == NULL)
459: return NULL;
460: *len = strlen(buffer);
461: while (*len == buflen && buffer[*len-1] != '\n') {
462: buffer = erealloc(buffer, 2*buflen + 1);
463: if (fgets(buffer + buflen, buflen + 1, stream) == NULL)
464: return NULL;
465: *len += strlen(buffer + buflen);
466: buflen *= 2;
467: }
468: return buffer;
1.6 millert 469: }
1.2 deraadt 470: #endif