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