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