| @@ -1,622 +1,626 @@ | | | @@ -1,622 +1,626 @@ |
1 | /* $NetBSD: util.c,v 1.13 2015/05/19 22:01:19 joerg Exp $ */ | | 1 | /* $NetBSD: util.c,v 1.14 2015/07/04 07:12:08 ryoon Exp $ */ |
2 | | | 2 | |
3 | /* | | 3 | /* |
4 | * Missing stuff from OS's | | 4 | * Missing stuff from OS's |
5 | * | | 5 | * |
6 | * $Id: util.c,v 1.13 2015/05/19 22:01:19 joerg Exp $ | | 6 | * $Id: util.c,v 1.14 2015/07/04 07:12:08 ryoon Exp $ |
7 | */ | | 7 | */ |
8 | #if defined(__MINT__) || defined(__linux__) | | 8 | #if defined(__MINT__) || defined(__linux__) |
9 | #include <signal.h> | | 9 | #include <signal.h> |
10 | #endif | | 10 | #endif |
11 | | | 11 | |
12 | #include "make.h" | | 12 | #include "make.h" |
13 | | | 13 | |
14 | #ifndef MAKE_NATIVE | | 14 | #ifndef MAKE_NATIVE |
15 | static char rcsid[] = "$NetBSD: util.c,v 1.13 2015/05/19 22:01:19 joerg Exp $"; | | 15 | static char rcsid[] = "$NetBSD: util.c,v 1.14 2015/07/04 07:12:08 ryoon Exp $"; |
16 | #else | | 16 | #else |
17 | #ifndef lint | | 17 | #ifndef lint |
18 | __RCSID("$NetBSD: util.c,v 1.13 2015/05/19 22:01:19 joerg Exp $"); | | 18 | __RCSID("$NetBSD: util.c,v 1.14 2015/07/04 07:12:08 ryoon Exp $"); |
19 | #endif | | 19 | #endif |
20 | #endif | | 20 | #endif |
21 | | | 21 | |
22 | #include <errno.h> | | 22 | #include <errno.h> |
23 | #include <time.h> | | 23 | #include <time.h> |
24 | #include <signal.h> | | 24 | #include <signal.h> |
25 | | | 25 | |
26 | #if !defined(HAVE_STRERROR) | | 26 | #if !defined(HAVE_STRERROR) |
27 | extern int errno, sys_nerr; | | 27 | extern int errno, sys_nerr; |
28 | extern char *sys_errlist[]; | | 28 | extern char *sys_errlist[]; |
29 | | | 29 | |
30 | char * | | 30 | char * |
31 | strerror(int e) | | 31 | strerror(int e) |
32 | { | | 32 | { |
33 | static char buf[100]; | | 33 | static char buf[100]; |
34 | if (e < 0 || e >= sys_nerr) { | | 34 | if (e < 0 || e >= sys_nerr) { |
35 | snprintf(buf, sizeof(buf), "Unknown error %d", e); | | 35 | snprintf(buf, sizeof(buf), "Unknown error %d", e); |
36 | return buf; | | 36 | return buf; |
37 | } | | 37 | } |
38 | else | | 38 | else |
39 | return sys_errlist[e]; | | 39 | return sys_errlist[e]; |
40 | } | | 40 | } |
41 | #endif | | 41 | #endif |
42 | | | 42 | |
43 | #if !defined(HAVE_GETENV) || !defined(HAVE_SETENV) || !defined(HAVE_UNSETENV) | | 43 | #if !defined(HAVE_GETENV) || !defined(HAVE_SETENV) || !defined(HAVE_UNSETENV) |
44 | extern char **environ; | | 44 | extern char **environ; |
45 | | | 45 | |
46 | static char * | | 46 | static char * |
47 | findenv(const char *name, int *offset) | | 47 | findenv(const char *name, int *offset) |
48 | { | | 48 | { |
49 | size_t i, len; | | 49 | size_t i, len; |
50 | char *p, *q; | | 50 | char *p, *q; |
51 | | | 51 | |
52 | len = strlen(name); | | 52 | len = strlen(name); |
53 | for (i = 0; (q = environ[i]); i++) { | | 53 | for (i = 0; (q = environ[i]); i++) { |
54 | p = strchr(q, '='); | | 54 | p = strchr(q, '='); |
55 | if (p == NULL || p - q != len) | | 55 | if (p == NULL || p - q != len) |
56 | continue; | | 56 | continue; |
57 | if (strncmp(name, q, len) == 0) { | | 57 | if (strncmp(name, q, len) == 0) { |
58 | *offset = i; | | 58 | *offset = i; |
59 | return q + len + 1; | | 59 | return q + len + 1; |
60 | } | | 60 | } |
61 | } | | 61 | } |
62 | *offset = i; | | 62 | *offset = i; |
63 | return NULL; | | 63 | return NULL; |
64 | } | | 64 | } |
65 | | | 65 | |
66 | char * | | 66 | char * |
67 | getenv(const char *name) | | 67 | getenv(const char *name) |
68 | { | | 68 | { |
69 | int offset; | | 69 | int offset; |
70 | | | 70 | |
71 | return(findenv(name, &offset)); | | 71 | return(findenv(name, &offset)); |
72 | } | | 72 | } |
73 | | | 73 | |
74 | int | | 74 | int |
75 | unsetenv(const char *name) | | 75 | unsetenv(const char *name) |
76 | { | | 76 | { |
77 | char **p; | | 77 | char **p; |
78 | int offset; | | 78 | int offset; |
79 | | | 79 | |
80 | if (name == NULL || *name == '\0' || strchr(name, '=') != NULL) { | | 80 | if (name == NULL || *name == '\0' || strchr(name, '=') != NULL) { |
81 | errno = EINVAL; | | 81 | errno = EINVAL; |
82 | return -1; | | 82 | return -1; |
83 | } | | 83 | } |
84 | | | 84 | |
85 | while (findenv(name, &offset)) { /* if set multiple times */ | | 85 | while (findenv(name, &offset)) { /* if set multiple times */ |
86 | for (p = &environ[offset];; ++p) | | 86 | for (p = &environ[offset];; ++p) |
87 | if (!(*p = *(p + 1))) | | 87 | if (!(*p = *(p + 1))) |
88 | break; | | 88 | break; |
89 | } | | 89 | } |
90 | return 0; | | 90 | return 0; |
91 | } | | 91 | } |
92 | | | 92 | |
93 | int | | 93 | int |
94 | setenv(const char *name, const char *value, int rewrite) | | 94 | setenv(const char *name, const char *value, int rewrite) |
95 | { | | 95 | { |
96 | char *c, **newenv; | | 96 | char *c, **newenv; |
97 | const char *cc; | | 97 | const char *cc; |
98 | size_t l_value, size; | | 98 | size_t l_value, size; |
99 | int offset; | | 99 | int offset; |
100 | | | 100 | |
101 | if (name == NULL || value == NULL) { | | 101 | if (name == NULL || value == NULL) { |
102 | errno = EINVAL; | | 102 | errno = EINVAL; |
103 | return -1; | | 103 | return -1; |
104 | } | | 104 | } |
105 | | | 105 | |
106 | if (*value == '=') /* no `=' in value */ | | 106 | if (*value == '=') /* no `=' in value */ |
107 | ++value; | | 107 | ++value; |
108 | l_value = strlen(value); | | 108 | l_value = strlen(value); |
109 | | | 109 | |
110 | /* find if already exists */ | | 110 | /* find if already exists */ |
111 | if ((c = findenv(name, &offset))) { | | 111 | if ((c = findenv(name, &offset))) { |
112 | if (!rewrite) | | 112 | if (!rewrite) |
113 | return 0; | | 113 | return 0; |
114 | if (strlen(c) >= l_value) /* old larger; copy over */ | | 114 | if (strlen(c) >= l_value) /* old larger; copy over */ |
115 | goto copy; | | 115 | goto copy; |
116 | } else { /* create new slot */ | | 116 | } else { /* create new slot */ |
117 | size = sizeof(char *) * (offset + 2); | | 117 | size = sizeof(char *) * (offset + 2); |
118 | if (savedEnv == environ) { /* just increase size */ | | 118 | if (savedEnv == environ) { /* just increase size */ |
119 | if ((newenv = realloc(savedEnv, size)) == NULL) | | 119 | if ((newenv = realloc(savedEnv, size)) == NULL) |
120 | return -1; | | 120 | return -1; |
121 | savedEnv = newenv; | | 121 | savedEnv = newenv; |
122 | } else { /* get new space */ | | 122 | } else { /* get new space */ |
123 | /* | | 123 | /* |
124 | * We don't free here because we don't know if | | 124 | * We don't free here because we don't know if |
125 | * the first allocation is valid on all OS's | | 125 | * the first allocation is valid on all OS's |
126 | */ | | 126 | */ |
127 | if ((savedEnv = malloc(size)) == NULL) | | 127 | if ((savedEnv = malloc(size)) == NULL) |
128 | return -1; | | 128 | return -1; |
129 | (void)memcpy(savedEnv, environ, size - sizeof(char *)); | | 129 | (void)memcpy(savedEnv, environ, size - sizeof(char *)); |
130 | } | | 130 | } |
131 | environ = savedEnv; | | 131 | environ = savedEnv; |
132 | environ[offset + 1] = NULL; | | 132 | environ[offset + 1] = NULL; |
133 | } | | 133 | } |
134 | for (cc = name; *cc && *cc != '='; ++cc) /* no `=' in name */ | | 134 | for (cc = name; *cc && *cc != '='; ++cc) /* no `=' in name */ |
135 | continue; | | 135 | continue; |
136 | size = cc - name; | | 136 | size = cc - name; |
137 | /* name + `=' + value */ | | 137 | /* name + `=' + value */ |
138 | if ((environ[offset] = malloc(size + l_value + 2)) == NULL) | | 138 | if ((environ[offset] = malloc(size + l_value + 2)) == NULL) |
139 | return -1; | | 139 | return -1; |
140 | c = environ[offset]; | | 140 | c = environ[offset]; |
141 | (void)memcpy(c, name, size); | | 141 | (void)memcpy(c, name, size); |
142 | c += size; | | 142 | c += size; |
143 | *c++ = '='; | | 143 | *c++ = '='; |
144 | copy: | | 144 | copy: |
145 | (void)memcpy(c, value, l_value + 1); | | 145 | (void)memcpy(c, value, l_value + 1); |
146 | return 0; | | 146 | return 0; |
147 | } | | 147 | } |
148 | | | 148 | |
149 | #ifdef TEST | | 149 | #ifdef TEST |
150 | int | | 150 | int |
151 | main(int argc, char *argv[]) | | 151 | main(int argc, char *argv[]) |
152 | { | | 152 | { |
153 | setenv(argv[1], argv[2], 0); | | 153 | setenv(argv[1], argv[2], 0); |
154 | printf("%s\n", getenv(argv[1])); | | 154 | printf("%s\n", getenv(argv[1])); |
155 | unsetenv(argv[1]); | | 155 | unsetenv(argv[1]); |
156 | printf("%s\n", getenv(argv[1])); | | 156 | printf("%s\n", getenv(argv[1])); |
157 | return 0; | | 157 | return 0; |
158 | } | | 158 | } |
159 | #endif | | 159 | #endif |
160 | | | 160 | |
161 | #endif | | 161 | #endif |
162 | | | 162 | |
163 | | | 163 | |
164 | #if defined(__hpux__) || defined(__hpux) | | 164 | #if defined(__hpux__) || defined(__hpux) |
165 | /* strrcpy(): | | 165 | /* strrcpy(): |
166 | * Like strcpy, going backwards and returning the new pointer | | 166 | * Like strcpy, going backwards and returning the new pointer |
167 | */ | | 167 | */ |
168 | static char * | | 168 | static char * |
169 | strrcpy(char *ptr, char *str) | | 169 | strrcpy(char *ptr, char *str) |
170 | { | | 170 | { |
171 | int len = strlen(str); | | 171 | int len = strlen(str); |
172 | | | 172 | |
173 | while (len) | | 173 | while (len) |
174 | *--ptr = str[--len]; | | 174 | *--ptr = str[--len]; |
175 | | | 175 | |
176 | return (ptr); | | 176 | return (ptr); |
177 | } /* end strrcpy */ | | 177 | } /* end strrcpy */ |
178 | | | 178 | |
179 | | | 179 | |
180 | char *sys_siglist[] = { | | 180 | char *sys_siglist[] = { |
181 | "Signal 0", | | 181 | "Signal 0", |
182 | "Hangup", /* SIGHUP */ | | 182 | "Hangup", /* SIGHUP */ |
183 | "Interrupt", /* SIGINT */ | | 183 | "Interrupt", /* SIGINT */ |
184 | "Quit", /* SIGQUIT */ | | 184 | "Quit", /* SIGQUIT */ |
185 | "Illegal instruction", /* SIGILL */ | | 185 | "Illegal instruction", /* SIGILL */ |
186 | "Trace/BPT trap", /* SIGTRAP */ | | 186 | "Trace/BPT trap", /* SIGTRAP */ |
187 | "IOT trap", /* SIGIOT */ | | 187 | "IOT trap", /* SIGIOT */ |
188 | "EMT trap", /* SIGEMT */ | | 188 | "EMT trap", /* SIGEMT */ |
189 | "Floating point exception", /* SIGFPE */ | | 189 | "Floating point exception", /* SIGFPE */ |
190 | "Killed", /* SIGKILL */ | | 190 | "Killed", /* SIGKILL */ |
191 | "Bus error", /* SIGBUS */ | | 191 | "Bus error", /* SIGBUS */ |
192 | "Segmentation fault", /* SIGSEGV */ | | 192 | "Segmentation fault", /* SIGSEGV */ |
193 | "Bad system call", /* SIGSYS */ | | 193 | "Bad system call", /* SIGSYS */ |
194 | "Broken pipe", /* SIGPIPE */ | | 194 | "Broken pipe", /* SIGPIPE */ |
195 | "Alarm clock", /* SIGALRM */ | | 195 | "Alarm clock", /* SIGALRM */ |
196 | "Terminated", /* SIGTERM */ | | 196 | "Terminated", /* SIGTERM */ |
197 | "User defined signal 1", /* SIGUSR1 */ | | 197 | "User defined signal 1", /* SIGUSR1 */ |
198 | "User defined signal 2", /* SIGUSR2 */ | | 198 | "User defined signal 2", /* SIGUSR2 */ |
199 | "Child exited", /* SIGCLD */ | | 199 | "Child exited", /* SIGCLD */ |
200 | "Power-fail restart", /* SIGPWR */ | | 200 | "Power-fail restart", /* SIGPWR */ |
201 | "Virtual timer expired", /* SIGVTALRM */ | | 201 | "Virtual timer expired", /* SIGVTALRM */ |
202 | "Profiling timer expired", /* SIGPROF */ | | 202 | "Profiling timer expired", /* SIGPROF */ |
203 | "I/O possible", /* SIGIO */ | | 203 | "I/O possible", /* SIGIO */ |
204 | "Window size changes", /* SIGWINDOW */ | | 204 | "Window size changes", /* SIGWINDOW */ |
205 | "Stopped (signal)", /* SIGSTOP */ | | 205 | "Stopped (signal)", /* SIGSTOP */ |
206 | "Stopped", /* SIGTSTP */ | | 206 | "Stopped", /* SIGTSTP */ |
207 | "Continued", /* SIGCONT */ | | 207 | "Continued", /* SIGCONT */ |
208 | "Stopped (tty input)", /* SIGTTIN */ | | 208 | "Stopped (tty input)", /* SIGTTIN */ |
209 | "Stopped (tty output)", /* SIGTTOU */ | | 209 | "Stopped (tty output)", /* SIGTTOU */ |
210 | "Urgent I/O condition", /* SIGURG */ | | 210 | "Urgent I/O condition", /* SIGURG */ |
211 | "Remote lock lost (NFS)", /* SIGLOST */ | | 211 | "Remote lock lost (NFS)", /* SIGLOST */ |
212 | "Signal 31", /* reserved */ | | 212 | "Signal 31", /* reserved */ |
213 | "DIL signal" /* SIGDIL */ | | 213 | "DIL signal" /* SIGDIL */ |
214 | }; | | 214 | }; |
215 | #endif /* __hpux__ || __hpux */ | | 215 | #endif /* __hpux__ || __hpux */ |
216 | | | 216 | |
217 | #if defined(__hpux__) || defined(__hpux) | | 217 | #if defined(__hpux__) || defined(__hpux) |
218 | #include <sys/types.h> | | 218 | #include <sys/types.h> |
219 | #include <sys/syscall.h> | | 219 | #include <sys/syscall.h> |
220 | #include <sys/signal.h> | | 220 | #include <sys/signal.h> |
221 | #include <sys/stat.h> | | 221 | #include <sys/stat.h> |
222 | #include <dirent.h> | | 222 | #include <dirent.h> |
223 | #include <sys/time.h> | | 223 | #include <sys/time.h> |
224 | #include <unistd.h> | | 224 | #include <unistd.h> |
225 | | | 225 | |
226 | int | | 226 | int |
227 | killpg(int pid, int sig) | | 227 | killpg(int pid, int sig) |
228 | { | | 228 | { |
229 | return kill(-pid, sig); | | 229 | return kill(-pid, sig); |
230 | } | | 230 | } |
231 | | | 231 | |
232 | #if !defined(__hpux__) && !defined(__hpux) | | 232 | #if !defined(__hpux__) && !defined(__hpux) |
233 | void | | 233 | void |
234 | srandom(long seed) | | 234 | srandom(long seed) |
235 | { | | 235 | { |
236 | srand48(seed); | | 236 | srand48(seed); |
237 | } | | 237 | } |
238 | | | 238 | |
239 | long | | 239 | long |
240 | random(void) | | 240 | random(void) |
241 | { | | 241 | { |
242 | return lrand48(); | | 242 | return lrand48(); |
243 | } | | 243 | } |
244 | #endif | | 244 | #endif |
245 | | | 245 | |
246 | #if !defined(__hpux__) && !defined(__hpux) | | 246 | #if !defined(__hpux__) && !defined(__hpux) |
247 | int | | 247 | int |
248 | utimes(char *file, struct timeval tvp[2]) | | 248 | utimes(char *file, struct timeval tvp[2]) |
249 | { | | 249 | { |
250 | struct utimbuf t; | | 250 | struct utimbuf t; |
251 | | | 251 | |
252 | t.actime = tvp[0].tv_sec; | | 252 | t.actime = tvp[0].tv_sec; |
253 | t.modtime = tvp[1].tv_sec; | | 253 | t.modtime = tvp[1].tv_sec; |
254 | return(utime(file, &t)); | | 254 | return(utime(file, &t)); |
255 | } | | 255 | } |
256 | #endif | | 256 | #endif |
257 | | | 257 | |
258 | #if !defined(BSD) && !defined(d_fileno) | | 258 | #if !defined(BSD) && !defined(d_fileno) |
259 | # define d_fileno d_ino | | 259 | # define d_fileno d_ino |
260 | #endif | | 260 | #endif |
261 | | | 261 | |
262 | #ifndef DEV_DEV_COMPARE | | 262 | #ifndef DEV_DEV_COMPARE |
263 | # define DEV_DEV_COMPARE(a, b) ((a) == (b)) | | 263 | # define DEV_DEV_COMPARE(a, b) ((a) == (b)) |
264 | #endif | | 264 | #endif |
265 | #define ISDOT(c) ((c)[0] == '.' && (((c)[1] == '\0') || ((c)[1] == '/'))) | | 265 | #define ISDOT(c) ((c)[0] == '.' && (((c)[1] == '\0') || ((c)[1] == '/'))) |
266 | #define ISDOTDOT(c) ((c)[0] == '.' && ISDOT(&((c)[1]))) | | 266 | #define ISDOTDOT(c) ((c)[0] == '.' && ISDOT(&((c)[1]))) |
267 | | | 267 | |
268 | char * | | 268 | char * |
269 | getwd(char *pathname) | | 269 | getwd(char *pathname) |
270 | { | | 270 | { |
271 | DIR *dp; | | 271 | DIR *dp; |
272 | struct dirent *d; | | 272 | struct dirent *d; |
273 | extern int errno; | | 273 | extern int errno; |
274 | | | 274 | |
275 | struct stat st_root, st_cur, st_next, st_dotdot; | | 275 | struct stat st_root, st_cur, st_next, st_dotdot; |
276 | char pathbuf[MAXPATHLEN], nextpathbuf[MAXPATHLEN * 2]; | | 276 | char pathbuf[MAXPATHLEN], nextpathbuf[MAXPATHLEN * 2]; |
277 | char *pathptr, *nextpathptr, *cur_name_add; | | 277 | char *pathptr, *nextpathptr, *cur_name_add; |
278 | | | 278 | |
279 | /* find the inode of root */ | | 279 | /* find the inode of root */ |
280 | if (stat("/", &st_root) == -1) { | | 280 | if (stat("/", &st_root) == -1) { |
281 | (void)sprintf(pathname, | | 281 | (void)sprintf(pathname, |
282 | "getwd: Cannot stat \"/\" (%s)", strerror(errno)); | | 282 | "getwd: Cannot stat \"/\" (%s)", strerror(errno)); |
283 | return NULL; | | 283 | return NULL; |
284 | } | | 284 | } |
285 | pathbuf[MAXPATHLEN - 1] = '\0'; | | 285 | pathbuf[MAXPATHLEN - 1] = '\0'; |
286 | pathptr = &pathbuf[MAXPATHLEN - 1]; | | 286 | pathptr = &pathbuf[MAXPATHLEN - 1]; |
287 | nextpathbuf[MAXPATHLEN - 1] = '\0'; | | 287 | nextpathbuf[MAXPATHLEN - 1] = '\0'; |
288 | cur_name_add = nextpathptr = &nextpathbuf[MAXPATHLEN - 1]; | | 288 | cur_name_add = nextpathptr = &nextpathbuf[MAXPATHLEN - 1]; |
289 | | | 289 | |
290 | /* find the inode of the current directory */ | | 290 | /* find the inode of the current directory */ |
291 | if (lstat(".", &st_cur) == -1) { | | 291 | if (lstat(".", &st_cur) == -1) { |
292 | (void)sprintf(pathname, | | 292 | (void)sprintf(pathname, |
293 | "getwd: Cannot stat \".\" (%s)", strerror(errno)); | | 293 | "getwd: Cannot stat \".\" (%s)", strerror(errno)); |
294 | return NULL; | | 294 | return NULL; |
295 | } | | 295 | } |
296 | nextpathptr = strrcpy(nextpathptr, "../"); | | 296 | nextpathptr = strrcpy(nextpathptr, "../"); |
297 | | | 297 | |
298 | /* Descend to root */ | | 298 | /* Descend to root */ |
299 | for (;;) { | | 299 | for (;;) { |
300 | | | 300 | |
301 | /* look if we found root yet */ | | 301 | /* look if we found root yet */ |
302 | if (st_cur.st_ino == st_root.st_ino && | | 302 | if (st_cur.st_ino == st_root.st_ino && |
303 | DEV_DEV_COMPARE(st_cur.st_dev, st_root.st_dev)) { | | 303 | DEV_DEV_COMPARE(st_cur.st_dev, st_root.st_dev)) { |
304 | (void)strcpy(pathname, *pathptr != '/' ? "/" : pathptr); | | 304 | (void)strcpy(pathname, *pathptr != '/' ? "/" : pathptr); |
305 | return (pathname); | | 305 | return (pathname); |
306 | } | | 306 | } |
307 | | | 307 | |
308 | /* open the parent directory */ | | 308 | /* open the parent directory */ |
309 | if (stat(nextpathptr, &st_dotdot) == -1) { | | 309 | if (stat(nextpathptr, &st_dotdot) == -1) { |
310 | (void)sprintf(pathname, | | 310 | (void)sprintf(pathname, |
311 | "getwd: Cannot stat directory \"%s\" (%s)", | | 311 | "getwd: Cannot stat directory \"%s\" (%s)", |
312 | nextpathptr, strerror(errno)); | | 312 | nextpathptr, strerror(errno)); |
313 | return NULL; | | 313 | return NULL; |
314 | } | | 314 | } |
315 | if ((dp = opendir(nextpathptr)) == NULL) { | | 315 | if ((dp = opendir(nextpathptr)) == NULL) { |
316 | (void)sprintf(pathname, | | 316 | (void)sprintf(pathname, |
317 | "getwd: Cannot open directory \"%s\" (%s)", | | 317 | "getwd: Cannot open directory \"%s\" (%s)", |
318 | nextpathptr, strerror(errno)); | | 318 | nextpathptr, strerror(errno)); |
319 | return NULL; | | 319 | return NULL; |
320 | } | | 320 | } |
321 | | | 321 | |
322 | /* look in the parent for the entry with the same inode */ | | 322 | /* look in the parent for the entry with the same inode */ |
323 | if (DEV_DEV_COMPARE(st_dotdot.st_dev, st_cur.st_dev)) { | | 323 | if (DEV_DEV_COMPARE(st_dotdot.st_dev, st_cur.st_dev)) { |
324 | /* Parent has same device. No need to stat every member */ | | 324 | /* Parent has same device. No need to stat every member */ |
325 | for (d = readdir(dp); d != NULL; d = readdir(dp)) | | 325 | for (d = readdir(dp); d != NULL; d = readdir(dp)) |
326 | if (d->d_fileno == st_cur.st_ino) | | 326 | if (d->d_fileno == st_cur.st_ino) |
327 | break; | | 327 | break; |
328 | } | | 328 | } |
329 | else { | | 329 | else { |
330 | /* | | 330 | /* |
331 | * Parent has a different device. This is a mount point so we | | 331 | * Parent has a different device. This is a mount point so we |
332 | * need to stat every member | | 332 | * need to stat every member |
333 | */ | | 333 | */ |
334 | for (d = readdir(dp); d != NULL; d = readdir(dp)) { | | 334 | for (d = readdir(dp); d != NULL; d = readdir(dp)) { |
335 | if (ISDOT(d->d_name) || ISDOTDOT(d->d_name)) | | 335 | if (ISDOT(d->d_name) || ISDOTDOT(d->d_name)) |
336 | continue; | | 336 | continue; |
337 | (void)strcpy(cur_name_add, d->d_name); | | 337 | (void)strcpy(cur_name_add, d->d_name); |
338 | if (lstat(nextpathptr, &st_next) == -1) { | | 338 | if (lstat(nextpathptr, &st_next) == -1) { |
339 | (void)sprintf(pathname, | | 339 | (void)sprintf(pathname, |
340 | "getwd: Cannot stat \"%s\" (%s)", | | 340 | "getwd: Cannot stat \"%s\" (%s)", |
341 | d->d_name, strerror(errno)); | | 341 | d->d_name, strerror(errno)); |
342 | (void)closedir(dp); | | 342 | (void)closedir(dp); |
343 | return NULL; | | 343 | return NULL; |
344 | } | | 344 | } |
345 | /* check if we found it yet */ | | 345 | /* check if we found it yet */ |
346 | if (st_next.st_ino == st_cur.st_ino && | | 346 | if (st_next.st_ino == st_cur.st_ino && |
347 | DEV_DEV_COMPARE(st_next.st_dev, st_cur.st_dev)) | | 347 | DEV_DEV_COMPARE(st_next.st_dev, st_cur.st_dev)) |
348 | break; | | 348 | break; |
349 | } | | 349 | } |
350 | } | | 350 | } |
351 | if (d == NULL) { | | 351 | if (d == NULL) { |
352 | (void)sprintf(pathname, | | 352 | (void)sprintf(pathname, |
353 | "getwd: Cannot find \".\" in \"..\""); | | 353 | "getwd: Cannot find \".\" in \"..\""); |
354 | (void)closedir(dp); | | 354 | (void)closedir(dp); |
355 | return NULL; | | 355 | return NULL; |
356 | } | | 356 | } |
357 | st_cur = st_dotdot; | | 357 | st_cur = st_dotdot; |
358 | pathptr = strrcpy(pathptr, d->d_name); | | 358 | pathptr = strrcpy(pathptr, d->d_name); |
359 | pathptr = strrcpy(pathptr, "/"); | | 359 | pathptr = strrcpy(pathptr, "/"); |
360 | nextpathptr = strrcpy(nextpathptr, "../"); | | 360 | nextpathptr = strrcpy(nextpathptr, "../"); |
361 | (void)closedir(dp); | | 361 | (void)closedir(dp); |
362 | *cur_name_add = '\0'; | | 362 | *cur_name_add = '\0'; |
363 | } | | 363 | } |
364 | } /* end getwd */ | | 364 | } /* end getwd */ |
365 | | | 365 | |
366 | #endif /* __hpux */ | | 366 | #endif /* __hpux */ |
367 | | | 367 | |
368 | #if !defined(HAVE_GETCWD) | | 368 | #if !defined(HAVE_GETCWD) |
369 | char * | | 369 | char * |
370 | getcwd(path, sz) | | 370 | getcwd(path, sz) |
371 | char *path; | | 371 | char *path; |
372 | int sz; | | 372 | int sz; |
373 | { | | 373 | { |
374 | return getwd(path); | | 374 | return getwd(path); |
375 | } | | 375 | } |
376 | #endif | | 376 | #endif |
377 | | | 377 | |
378 | /* force posix signals */ | | 378 | /* force posix signals */ |
379 | void (* | | 379 | void (* |
380 | bmake_signal(int s, void (*a)(int)))(int) | | 380 | bmake_signal(int s, void (*a)(int)))(int) |
381 | { | | 381 | { |
382 | struct sigaction sa, osa; | | 382 | struct sigaction sa, osa; |
383 | | | 383 | |
384 | sa.sa_handler = a; | | 384 | sa.sa_handler = a; |
385 | sigemptyset(&sa.sa_mask); | | 385 | sigemptyset(&sa.sa_mask); |
| | | 386 | #ifdef SA_RESTART |
386 | sa.sa_flags = SA_RESTART; | | 387 | sa.sa_flags = SA_RESTART; |
| | | 388 | #else |
| | | 389 | sa.sa_flags = 0; |
| | | 390 | #endif |
387 | | | 391 | |
388 | if (sigaction(s, &sa, &osa) == -1) | | 392 | if (sigaction(s, &sa, &osa) == -1) |
389 | return SIG_ERR; | | 393 | return SIG_ERR; |
390 | else | | 394 | else |
391 | return osa.sa_handler; | | 395 | return osa.sa_handler; |
392 | } | | 396 | } |
393 | | | 397 | |
394 | #if !defined(HAVE_VSNPRINTF) || !defined(HAVE_VASPRINTF) | | 398 | #if !defined(HAVE_VSNPRINTF) || !defined(HAVE_VASPRINTF) |
395 | #include <stdarg.h> | | 399 | #include <stdarg.h> |
396 | #endif | | 400 | #endif |
397 | | | 401 | |
398 | #if !defined(HAVE_VSNPRINTF) | | 402 | #if !defined(HAVE_VSNPRINTF) |
399 | #if !defined(__osf__) | | 403 | #if !defined(__osf__) |
400 | #ifdef _IOSTRG | | 404 | #ifdef _IOSTRG |
401 | #define STRFLAG (_IOSTRG|_IOWRT) /* no _IOWRT: avoid stdio bug */ | | 405 | #define STRFLAG (_IOSTRG|_IOWRT) /* no _IOWRT: avoid stdio bug */ |
402 | #else | | 406 | #else |
403 | #if 0 | | 407 | #if 0 |
404 | #define STRFLAG (_IOREAD) /* XXX: Assume svr4 stdio */ | | 408 | #define STRFLAG (_IOREAD) /* XXX: Assume svr4 stdio */ |
405 | #endif | | 409 | #endif |
406 | #endif /* _IOSTRG */ | | 410 | #endif /* _IOSTRG */ |
407 | #endif /* __osf__ */ | | 411 | #endif /* __osf__ */ |
408 | | | 412 | |
409 | int | | 413 | int |
410 | vsnprintf(char *s, size_t n, const char *fmt, va_list args) | | 414 | vsnprintf(char *s, size_t n, const char *fmt, va_list args) |
411 | { | | 415 | { |
412 | #ifdef STRFLAG | | 416 | #ifdef STRFLAG |
413 | FILE fakebuf; | | 417 | FILE fakebuf; |
414 | | | 418 | |
415 | fakebuf._flag = STRFLAG; | | 419 | fakebuf._flag = STRFLAG; |
416 | /* | | 420 | /* |
417 | * Some os's are char * _ptr, others are unsigned char *_ptr... | | 421 | * Some os's are char * _ptr, others are unsigned char *_ptr... |
418 | * We cast to void * to make everyone happy. | | 422 | * We cast to void * to make everyone happy. |
419 | */ | | 423 | */ |
420 | fakebuf._ptr = (void *)s; | | 424 | fakebuf._ptr = (void *)s; |
421 | fakebuf._cnt = n-1; | | 425 | fakebuf._cnt = n-1; |
422 | fakebuf._file = -1; | | 426 | fakebuf._file = -1; |
423 | _doprnt(fmt, args, &fakebuf); | | 427 | _doprnt(fmt, args, &fakebuf); |
424 | fakebuf._cnt++; | | 428 | fakebuf._cnt++; |
425 | putc('\0', &fakebuf); | | 429 | putc('\0', &fakebuf); |
426 | if (fakebuf._cnt<0) | | 430 | if (fakebuf._cnt<0) |
427 | fakebuf._cnt = 0; | | 431 | fakebuf._cnt = 0; |
428 | return (n-fakebuf._cnt-1); | | 432 | return (n-fakebuf._cnt-1); |
429 | #else | | 433 | #else |
430 | #ifndef _PATH_DEVNULL | | 434 | #ifndef _PATH_DEVNULL |
431 | # define _PATH_DEVNULL "/dev/null" | | 435 | # define _PATH_DEVNULL "/dev/null" |
432 | #endif | | 436 | #endif |
433 | /* | | 437 | /* |
434 | * Rats... we don't want to clobber anything... | | 438 | * Rats... we don't want to clobber anything... |
435 | * do a printf to /dev/null to see how much space we need. | | 439 | * do a printf to /dev/null to see how much space we need. |
436 | */ | | 440 | */ |
437 | static FILE *nullfp; | | 441 | static FILE *nullfp; |
438 | int need = 0; /* XXX what's a useful error return? */ | | 442 | int need = 0; /* XXX what's a useful error return? */ |
439 | | | 443 | |
440 | if (!nullfp) | | 444 | if (!nullfp) |
441 | nullfp = fopen(_PATH_DEVNULL, "w"); | | 445 | nullfp = fopen(_PATH_DEVNULL, "w"); |
442 | if (nullfp) { | | 446 | if (nullfp) { |
443 | need = vfprintf(nullfp, fmt, args); | | 447 | need = vfprintf(nullfp, fmt, args); |
444 | if (need < n) | | 448 | if (need < n) |
445 | (void)vsprintf(s, fmt, args); | | 449 | (void)vsprintf(s, fmt, args); |
446 | } | | 450 | } |
447 | return need; | | 451 | return need; |
448 | #endif | | 452 | #endif |
449 | } | | 453 | } |
450 | #endif | | 454 | #endif |
451 | | | 455 | |
452 | #if !defined(HAVE_SNPRINTF) | | 456 | #if !defined(HAVE_SNPRINTF) |
453 | int | | 457 | int |
454 | snprintf(char *s, size_t n, const char *fmt, ...) | | 458 | snprintf(char *s, size_t n, const char *fmt, ...) |
455 | { | | 459 | { |
456 | va_list ap; | | 460 | va_list ap; |
457 | int rv; | | 461 | int rv; |
458 | | | 462 | |
459 | va_start(ap, fmt); | | 463 | va_start(ap, fmt); |
460 | rv = vsnprintf(s, n, fmt, ap); | | 464 | rv = vsnprintf(s, n, fmt, ap); |
461 | va_end(ap); | | 465 | va_end(ap); |
462 | return rv; | | 466 | return rv; |
463 | } | | 467 | } |
464 | #endif | | 468 | #endif |
465 | | | 469 | |
466 | #if !defined(HAVE_STRFTIME) | | 470 | #if !defined(HAVE_STRFTIME) |
467 | size_t | | 471 | size_t |
468 | strftime(char *buf, size_t len, const char *fmt, const struct tm *tm) | | 472 | strftime(char *buf, size_t len, const char *fmt, const struct tm *tm) |
469 | { | | 473 | { |
470 | static char months[][4] = { | | 474 | static char months[][4] = { |
471 | "Jan", "Feb", "Mar", "Apr", "May", "Jun", | | 475 | "Jan", "Feb", "Mar", "Apr", "May", "Jun", |
472 | "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" | | 476 | "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" |
473 | }; | | 477 | }; |
474 | | | 478 | |
475 | size_t s; | | 479 | size_t s; |
476 | char *b = buf; | | 480 | char *b = buf; |
477 | | | 481 | |
478 | while (*fmt) { | | 482 | while (*fmt) { |
479 | if (len == 0) | | 483 | if (len == 0) |
480 | return buf - b; | | 484 | return buf - b; |
481 | if (*fmt != '%') { | | 485 | if (*fmt != '%') { |
482 | *buf++ = *fmt++; | | 486 | *buf++ = *fmt++; |
483 | len--; | | 487 | len--; |
484 | continue; | | 488 | continue; |
485 | } | | 489 | } |
486 | switch (*fmt++) { | | 490 | switch (*fmt++) { |
487 | case '%': | | 491 | case '%': |
488 | *buf++ = '%'; | | 492 | *buf++ = '%'; |
489 | len--; | | 493 | len--; |
490 | if (len == 0) return buf - b; | | 494 | if (len == 0) return buf - b; |
491 | /*FALLTHROUGH*/ | | 495 | /*FALLTHROUGH*/ |
492 | case '\0': | | 496 | case '\0': |
493 | *buf = '%'; | | 497 | *buf = '%'; |
494 | s = 1; | | 498 | s = 1; |
495 | break; | | 499 | break; |
496 | case 'k': | | 500 | case 'k': |
497 | s = snprintf(buf, len, "%d", tm->tm_hour); | | 501 | s = snprintf(buf, len, "%d", tm->tm_hour); |
498 | break; | | 502 | break; |
499 | case 'M': | | 503 | case 'M': |
500 | s = snprintf(buf, len, "%02d", tm->tm_min); | | 504 | s = snprintf(buf, len, "%02d", tm->tm_min); |
501 | break; | | 505 | break; |
502 | case 'S': | | 506 | case 'S': |
503 | s = snprintf(buf, len, "%02d", tm->tm_sec); | | 507 | s = snprintf(buf, len, "%02d", tm->tm_sec); |
504 | break; | | 508 | break; |
505 | case 'b': | | 509 | case 'b': |
506 | if (tm->tm_mon >= 12) | | 510 | if (tm->tm_mon >= 12) |
507 | return buf - b; | | 511 | return buf - b; |
508 | s = snprintf(buf, len, "%s", months[tm->tm_mon]); | | 512 | s = snprintf(buf, len, "%s", months[tm->tm_mon]); |
509 | break; | | 513 | break; |
510 | case 'd': | | 514 | case 'd': |
511 | s = snprintf(buf, len, "%02d", tm->tm_mday); | | 515 | s = snprintf(buf, len, "%02d", tm->tm_mday); |
512 | break; | | 516 | break; |
513 | case 'Y': | | 517 | case 'Y': |
514 | s = snprintf(buf, len, "%d", 1900 + tm->tm_year); | | 518 | s = snprintf(buf, len, "%d", 1900 + tm->tm_year); |
515 | break; | | 519 | break; |
516 | default: | | 520 | default: |
517 | s = snprintf(buf, len, "Unsupported format %c", | | 521 | s = snprintf(buf, len, "Unsupported format %c", |
518 | fmt[-1]); | | 522 | fmt[-1]); |
519 | break; | | 523 | break; |
520 | } | | 524 | } |
521 | buf += s; | | 525 | buf += s; |
522 | len -= s; | | 526 | len -= s; |
523 | } | | 527 | } |
524 | } | | 528 | } |
525 | #endif | | 529 | #endif |
526 | | | 530 | |
527 | #if !defined(HAVE_KILLPG) | | 531 | #if !defined(HAVE_KILLPG) |
528 | #if !defined(__hpux__) && !defined(__hpux) | | 532 | #if !defined(__hpux__) && !defined(__hpux) |
529 | int | | 533 | int |
530 | killpg(int pid, int sig) | | 534 | killpg(int pid, int sig) |
531 | { | | 535 | { |
532 | return kill(-pid, sig); | | 536 | return kill(-pid, sig); |
533 | } | | 537 | } |
534 | #endif | | 538 | #endif |
535 | #endif | | 539 | #endif |
536 | | | 540 | |
537 | #if !defined(HAVE_WARNX) | | 541 | #if !defined(HAVE_WARNX) |
538 | static void | | 542 | static void |
539 | vwarnx(const char *fmt, va_list args) | | 543 | vwarnx(const char *fmt, va_list args) |
540 | { | | 544 | { |
541 | fprintf(stderr, "%s: ", progname); | | 545 | fprintf(stderr, "%s: ", progname); |
542 | if ((fmt)) { | | 546 | if ((fmt)) { |
543 | vfprintf(stderr, fmt, args); | | 547 | vfprintf(stderr, fmt, args); |
544 | fprintf(stderr, ": "); | | 548 | fprintf(stderr, ": "); |
545 | } | | 549 | } |
546 | } | | 550 | } |
547 | #endif | | 551 | #endif |
548 | | | 552 | |
549 | #if !defined(HAVE_WARN) | | 553 | #if !defined(HAVE_WARN) |
550 | static void | | 554 | static void |
551 | vwarn(const char *fmt, va_list args) | | 555 | vwarn(const char *fmt, va_list args) |
552 | { | | 556 | { |
553 | vwarnx(fmt, args); | | 557 | vwarnx(fmt, args); |
554 | fprintf(stderr, "%s\n", strerror(errno)); | | 558 | fprintf(stderr, "%s\n", strerror(errno)); |
555 | } | | 559 | } |
556 | #endif | | 560 | #endif |
557 | | | 561 | |
558 | #if !defined(HAVE_ERR) | | 562 | #if !defined(HAVE_ERR) |
559 | static void | | 563 | static void |
560 | verr(int eval, const char *fmt, va_list args) | | 564 | verr(int eval, const char *fmt, va_list args) |
561 | { | | 565 | { |
562 | vwarn(fmt, args); | | 566 | vwarn(fmt, args); |
563 | exit(eval); | | 567 | exit(eval); |
564 | } | | 568 | } |
565 | #endif | | 569 | #endif |
566 | | | 570 | |
567 | #if !defined(HAVE_ERRX) | | 571 | #if !defined(HAVE_ERRX) |
568 | static void | | 572 | static void |
569 | verrx(int eval, const char *fmt, va_list args) | | 573 | verrx(int eval, const char *fmt, va_list args) |
570 | { | | 574 | { |
571 | vwarnx(fmt, args); | | 575 | vwarnx(fmt, args); |
572 | exit(eval); | | 576 | exit(eval); |
573 | } | | 577 | } |
574 | #endif | | 578 | #endif |
575 | | | 579 | |
576 | #if !defined(HAVE_ERR) | | 580 | #if !defined(HAVE_ERR) |
577 | void | | 581 | void |
578 | err(int eval, const char *fmt, ...) | | 582 | err(int eval, const char *fmt, ...) |
579 | { | | 583 | { |
580 | va_list ap; | | 584 | va_list ap; |
581 | | | 585 | |
582 | va_start(ap, fmt); | | 586 | va_start(ap, fmt); |
583 | verr(eval, fmt, ap); | | 587 | verr(eval, fmt, ap); |
584 | va_end(ap); | | 588 | va_end(ap); |
585 | } | | 589 | } |
586 | #endif | | 590 | #endif |
587 | | | 591 | |
588 | #if !defined(HAVE_ERRX) | | 592 | #if !defined(HAVE_ERRX) |
589 | void | | 593 | void |
590 | errx(int eval, const char *fmt, ...) | | 594 | errx(int eval, const char *fmt, ...) |
591 | { | | 595 | { |
592 | va_list ap; | | 596 | va_list ap; |
593 | | | 597 | |
594 | va_start(ap, fmt); | | 598 | va_start(ap, fmt); |
595 | verrx(eval, fmt, ap); | | 599 | verrx(eval, fmt, ap); |
596 | va_end(ap); | | 600 | va_end(ap); |
597 | } | | 601 | } |
598 | #endif | | 602 | #endif |
599 | | | 603 | |
600 | #if !defined(HAVE_WARN) | | 604 | #if !defined(HAVE_WARN) |
601 | void | | 605 | void |
602 | warn(const char *fmt, ...) | | 606 | warn(const char *fmt, ...) |
603 | { | | 607 | { |
604 | va_list ap; | | 608 | va_list ap; |
605 | | | 609 | |
606 | va_start(ap, fmt); | | 610 | va_start(ap, fmt); |
607 | vwarn(fmt, ap); | | 611 | vwarn(fmt, ap); |
608 | va_end(ap); | | 612 | va_end(ap); |
609 | } | | 613 | } |
610 | #endif | | 614 | #endif |
611 | | | 615 | |
612 | #if !defined(HAVE_WARNX) | | 616 | #if !defined(HAVE_WARNX) |
613 | void | | 617 | void |
614 | warnx(const char *fmt, ...) | | 618 | warnx(const char *fmt, ...) |
615 | { | | 619 | { |
616 | va_list ap; | | 620 | va_list ap; |
617 | | | 621 | |
618 | va_start(ap, fmt); | | 622 | va_start(ap, fmt); |
619 | vwarnx(fmt, ap); | | 623 | vwarnx(fmt, ap); |
620 | va_end(ap); | | 624 | va_end(ap); |
621 | } | | 625 | } |
622 | #endif | | 626 | #endif |