util.c revision 1.6 1 /* $NetBSD: util.c,v 1.6 1996/08/13 16:41:15 christos Exp $ */
2
3 /*
4 * Missing stuff from OS's
5 *
6 */
7
8 #ifndef lint
9 static char rcsid[] = "$Id: util.c,v 1.6 1996/08/13 16:41:15 christos Exp $";
10 #endif
11
12 #include <stdio.h>
13 #include "make.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
56 if (str == NULL)
57 return NULL;
58 len = strlen(str) + 1;
59 if ((p = malloc(len)) == NULL)
60 return NULL;
61
62 return memcpy(p, str, len);
63 }
64
65 #endif
66
67 #if defined(sun) || defined(__hpux) || defined(__sgi)
68
69 int
70 setenv(name, value, dum)
71 const char *name;
72 const char *value;
73 int dum;
74 {
75 register char *p;
76 int len = strlen(name) + strlen(value) + 2; /* = \0 */
77 char *ptr = (char*) malloc(len);
78
79 (void) dum;
80
81 if (ptr == NULL)
82 return -1;
83
84 p = ptr;
85
86 while (*name)
87 *p++ = *name++;
88
89 *p++ = '=';
90
91 while (*value)
92 *p++ = *value++;
93
94 *p = '\0';
95
96 len = putenv(ptr);
97 /* free(ptr); */
98 return len;
99 }
100 #endif
101
102 #ifdef __hpux
103 #include <sys/types.h>
104 #include <sys/param.h>
105 #include <sys/syscall.h>
106 #include <sys/signal.h>
107 #include <sys/stat.h>
108 #include <stdio.h>
109 #include <dirent.h>
110 #include <sys/time.h>
111 #include <time.h>
112 #include <unistd.h>
113
114
115 int
116 killpg(pid, sig)
117 int pid, sig;
118 {
119 return kill(-pid, sig);
120 }
121
122 void
123 srandom(seed)
124 long seed;
125 {
126 srand48(seed);
127 }
128
129 long
130 random()
131 {
132 return lrand48();
133 }
134
135 /* turn into bsd signals */
136 void (*
137 signal(s, a)) ()
138 int s;
139 void (*a)();
140 {
141 struct sigvec osv, sv;
142
143 (void) sigvector(s, (struct sigvec *) 0, &osv);
144 sv = osv;
145 sv.sv_handler = a;
146 #ifdef SV_BSDSIG
147 sv.sv_flags = SV_BSDSIG;
148 #endif
149
150 if (sigvector(s, &sv, (struct sigvec *) 0) == -1)
151 return (BADSIG);
152 return (osv.sv_handler);
153 }
154
155 #if !defined(BSD) && !defined(d_fileno)
156 # define d_fileno d_ino
157 #endif
158
159 #ifndef DEV_DEV_COMPARE
160 # define DEV_DEV_COMPARE(a, b) ((a) == (b))
161 #endif
162 #define ISDOT(c) ((c)[0] == '.' && (((c)[1] == '\0') || ((c)[1] == '/')))
163 #define ISDOTDOT(c) ((c)[0] == '.' && ISDOT(&((c)[1])))
164
165
166 /* strrcpy():
167 * Like strcpy, going backwards and returning the new pointer
168 */
169 static char *
170 strrcpy(ptr, str)
171 register char *ptr, *str;
172 {
173 register int len = strlen(str);
174
175 while (len)
176 *--ptr = str[--len];
177
178 return (ptr);
179 } /* end strrcpy */
180
181
182 char *
183 getwd(pathname)
184 char *pathname;
185 {
186 DIR *dp;
187 struct dirent *d;
188 extern int errno;
189
190 struct stat st_root, st_cur, st_next, st_dotdot;
191 char pathbuf[MAXPATHLEN], nextpathbuf[MAXPATHLEN * 2];
192 char *pathptr, *nextpathptr, *cur_name_add;
193
194 /* find the inode of root */
195 if (stat("/", &st_root) == -1) {
196 (void) sprintf(pathname,
197 "getwd: Cannot stat \"/\" (%s)", strerror(errno));
198 return (NULL);
199 }
200 pathbuf[MAXPATHLEN - 1] = '\0';
201 pathptr = &pathbuf[MAXPATHLEN - 1];
202 nextpathbuf[MAXPATHLEN - 1] = '\0';
203 cur_name_add = nextpathptr = &nextpathbuf[MAXPATHLEN - 1];
204
205 /* find the inode of the current directory */
206 if (lstat(".", &st_cur) == -1) {
207 (void) sprintf(pathname,
208 "getwd: Cannot stat \".\" (%s)", strerror(errno));
209 return (NULL);
210 }
211 nextpathptr = strrcpy(nextpathptr, "../");
212
213 /* Descend to root */
214 for (;;) {
215
216 /* look if we found root yet */
217 if (st_cur.st_ino == st_root.st_ino &&
218 DEV_DEV_COMPARE(st_cur.st_dev, st_root.st_dev)) {
219 (void) strcpy(pathname, *pathptr != '/' ? "/" : pathptr);
220 return (pathname);
221 }
222
223 /* open the parent directory */
224 if (stat(nextpathptr, &st_dotdot) == -1) {
225 (void) sprintf(pathname,
226 "getwd: Cannot stat directory \"%s\" (%s)",
227 nextpathptr, strerror(errno));
228 return (NULL);
229 }
230 if ((dp = opendir(nextpathptr)) == NULL) {
231 (void) sprintf(pathname,
232 "getwd: Cannot open directory \"%s\" (%s)",
233 nextpathptr, strerror(errno));
234 return (NULL);
235 }
236
237 /* look in the parent for the entry with the same inode */
238 if (DEV_DEV_COMPARE(st_dotdot.st_dev, st_cur.st_dev)) {
239 /* Parent has same device. No need to stat every member */
240 for (d = readdir(dp); d != NULL; d = readdir(dp))
241 if (d->d_fileno == st_cur.st_ino)
242 break;
243 }
244 else {
245 /*
246 * Parent has a different device. This is a mount point so we
247 * need to stat every member
248 */
249 for (d = readdir(dp); d != NULL; d = readdir(dp)) {
250 if (ISDOT(d->d_name) || ISDOTDOT(d->d_name))
251 continue;
252 (void) strcpy(cur_name_add, d->d_name);
253 if (lstat(nextpathptr, &st_next) == -1) {
254 (void) sprintf(pathname, "getwd: Cannot stat \"%s\" (%s)",
255 d->d_name, strerror(errno));
256 (void) closedir(dp);
257 return (NULL);
258 }
259 /* check if we found it yet */
260 if (st_next.st_ino == st_cur.st_ino &&
261 DEV_DEV_COMPARE(st_next.st_dev, st_cur.st_dev))
262 break;
263 }
264 }
265 if (d == NULL) {
266 (void) sprintf(pathname, "getwd: Cannot find \".\" in \"..\"");
267 (void) closedir(dp);
268 return (NULL);
269 }
270 st_cur = st_dotdot;
271 pathptr = strrcpy(pathptr, d->d_name);
272 pathptr = strrcpy(pathptr, "/");
273 nextpathptr = strrcpy(nextpathptr, "../");
274 (void) closedir(dp);
275 *cur_name_add = '\0';
276 }
277 } /* end getwd */
278
279
280 char *sys_siglist[] = {
281 "Signal 0",
282 "Hangup", /* SIGHUP */
283 "Interrupt", /* SIGINT */
284 "Quit", /* SIGQUIT */
285 "Illegal instruction", /* SIGILL */
286 "Trace/BPT trap", /* SIGTRAP */
287 "IOT trap", /* SIGIOT */
288 "EMT trap", /* SIGEMT */
289 "Floating point exception", /* SIGFPE */
290 "Killed", /* SIGKILL */
291 "Bus error", /* SIGBUS */
292 "Segmentation fault", /* SIGSEGV */
293 "Bad system call", /* SIGSYS */
294 "Broken pipe", /* SIGPIPE */
295 "Alarm clock", /* SIGALRM */
296 "Terminated", /* SIGTERM */
297 "User defined signal 1", /* SIGUSR1 */
298 "User defined signal 2", /* SIGUSR2 */
299 "Child exited", /* SIGCLD */
300 "Power-fail restart", /* SIGPWR */
301 "Virtual timer expired", /* SIGVTALRM */
302 "Profiling timer expired", /* SIGPROF */
303 "I/O possible", /* SIGIO */
304 "Window size changes", /* SIGWINDOW */
305 "Stopped (signal)", /* SIGSTOP */
306 "Stopped", /* SIGTSTP */
307 "Continued", /* SIGCONT */
308 "Stopped (tty input)", /* SIGTTIN */
309 "Stopped (tty output)", /* SIGTTOU */
310 "Urgent I/O condition", /* SIGURG */
311 "Remote lock lost (NFS)", /* SIGLOST */
312 "Signal 31", /* reserved */
313 "DIL signal" /* SIGDIL */
314 };
315
316 int
317 utimes(file, tvp)
318 char *file;
319 struct timeval tvp[2];
320 {
321 struct utimbuf t;
322
323 t.actime = tvp[0].tv_sec;
324 t.modtime = tvp[1].tv_sec;
325 return(utime(file, &t));
326 }
327
328
329 #endif /* __hpux */
330
331 #if defined(sun) && defined(__svr4__)
332 #include <signal.h>
333
334 /* turn into bsd signals */
335 void (*
336 signal(s, a)) ()
337 int s;
338 void (*a)();
339 {
340 struct sigaction sa, osa;
341
342 sa.sa_handler = a;
343 sigemptyset(&sa.sa_mask);
344 sa.sa_flags = SA_RESTART;
345
346 if (sigaction(s, &sa, &osa) == -1)
347 return SIG_ERR;
348 else
349 return osa.sa_handler;
350 }
351
352 #endif
353