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