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