Changeset 24 for branches/FREEBSD/src/kmk/util.c
- Timestamp:
- Nov 26, 2002, 10:24:54 PM (23 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/FREEBSD/src/kmk/util.c
r10 r24 1 1 /* 2 * Copyright (c) 2002 Juli Mallett. All rights reserved. 3 * Copyright (c) 1988, 1989, 1990, 1993 4 * The Regents of the University of California. All rights reserved. 5 * Copyright (c) 1989 by Berkeley Softworks 6 * All rights reserved. 2 * Missing stuff from OS's 3 */ 4 5 #ifndef lint 6 static char rcsid[] = "$FreeBSD: src/usr.bin/make/util.c,v 1.5.2.2 2001/02/13 03:13:58 will Exp $"; 7 #endif 8 9 #include <stdio.h> 10 #include <errno.h> 11 #include "make.h" 12 13 #if !__STDC__ 14 # ifndef const 15 # define const 16 # endif 17 #endif 18 19 #ifdef sun 20 extern int errno, sys_nerr; 21 extern char *sys_errlist[]; 22 23 char * 24 strerror(e) 25 int e; 26 { 27 static char buf[100]; 28 if (e < 0 || e >= sys_nerr) { 29 sprintf(buf, "Unknown error %d", e); 30 return buf; 31 } 32 else 33 return sys_errlist[e]; 34 } 35 #endif 36 37 #ifdef ultrix 38 #include <string.h> 39 40 /* strdup 7 41 * 8 * This code is derived from software contributed to Berkeley by 9 * Adam de Boor. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 3. All advertising materials mentioning features or use of this software 20 * must display the following acknowledgement: 21 * This product includes software developed by the University of 22 * California, Berkeley and its contributors. 23 * 4. Neither the name of the University nor the names of its contributors 24 * may be used to endorse or promote products derived from this software 25 * without specific prior written permission. 26 * 27 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 28 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 29 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 30 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 31 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 32 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 33 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 34 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 35 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 36 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 37 * SUCH DAMAGE. 38 * 39 * @(#)main.c 8.3 (Berkeley) 3/19/94 40 */ 41 42 #include <sys/cdefs.h> 43 __FBSDID("$FreeBSD: src/usr.bin/make/util.c,v 1.12 2002/10/10 19:27:48 jmallett Exp $"); 44 45 /*- 46 * util.c -- 47 * General utilitarian routines for make(1). 48 */ 49 50 #include <sys/types.h> 51 #include <sys/stat.h> 52 #include <err.h> 53 #include <stdlib.h> 54 #include <errno.h> 55 #include <fcntl.h> 56 #include <stdio.h> 57 #include <sysexits.h> 58 #include <stdarg.h> 59 #include <unistd.h> 60 61 #include "make.h" 62 #include "hash.h" 63 #include "dir.h" 64 #include "job.h" 65 #include "pathnames.h" 66 67 /*- 68 * Debug -- 69 * Print a debugging message given its format. 70 * 71 * Results: 72 * None. 73 * 74 * Side Effects: 75 * The message is printed. 76 */ 77 /* VARARGS */ 78 void 79 Debug(const char *fmt, ...) 80 { 81 va_list ap; 82 83 va_start(ap, fmt); 84 (void)vfprintf(stderr, fmt, ap); 85 va_end(ap); 86 (void)fflush(stderr); 87 } 88 89 /*- 90 * Error -- 91 * Print an error message given its format. 92 * 93 * Results: 94 * None. 95 * 96 * Side Effects: 97 * The message is printed. 98 */ 99 /* VARARGS */ 100 void 101 Error(const char *fmt, ...) 102 { 103 va_list ap; 104 105 va_start(ap, fmt); 106 (void)vfprintf(stderr, fmt, ap); 107 va_end(ap); 108 (void)fprintf(stderr, "\n"); 109 (void)fflush(stderr); 110 } 111 112 /*- 113 * Fatal -- 114 * Produce a Fatal error message. If jobs are running, waits for them 115 * to finish. 116 * 117 * Results: 118 * None 119 * 120 * Side Effects: 121 * The program exits 122 */ 123 /* VARARGS */ 124 void 125 Fatal(const char *fmt, ...) 126 { 127 va_list ap; 128 129 va_start(ap, fmt); 130 if (jobsRunning) 131 Job_Wait(); 132 133 (void)vfprintf(stderr, fmt, ap); 134 va_end(ap); 135 (void)fprintf(stderr, "\n"); 136 (void)fflush(stderr); 137 138 if (DEBUG(GRAPH2)) 139 Targ_PrintGraph(2); 140 exit(2); /* Not 1 so -q can distinguish error */ 141 } 142 143 /* 144 * Punt -- 145 * Major exception once jobs are being created. Kills all jobs, prints 146 * a message and exits. 147 * 148 * Results: 149 * None 150 * 151 * Side Effects: 152 * All children are killed indiscriminately and the program Lib_Exits 153 */ 154 /* VARARGS */ 155 void 156 Punt(const char *fmt, ...) 157 { 158 va_list ap; 159 160 va_start(ap, fmt); 161 (void)fprintf(stderr, "make: "); 162 (void)vfprintf(stderr, fmt, ap); 163 va_end(ap); 164 (void)fprintf(stderr, "\n"); 165 (void)fflush(stderr); 166 167 DieHorribly(); 168 } 169 170 /*- 171 * DieHorribly -- 172 * Exit without giving a message. 173 * 174 * Results: 175 * None 176 * 177 * Side Effects: 178 * A big one... 179 */ 180 void 181 DieHorribly(void) 182 { 183 if (jobsRunning) 184 Job_AbortAll(); 185 if (DEBUG(GRAPH2)) 186 Targ_PrintGraph(2); 187 exit(2); /* Not 1, so -q can distinguish error */ 188 } 189 190 /* 191 * Finish -- 192 * Called when aborting due to errors in child shell to signal 193 * abnormal exit, with the number of errors encountered in Make_Make. 194 * 195 * Results: 196 * None 197 * 198 * Side Effects: 199 * The program exits 200 */ 201 void 202 Finish(int errors) 203 { 204 Fatal("%d error%s", errors, errors == 1 ? "" : "s"); 205 } 206 207 /* 208 * emalloc -- 209 * malloc, but die on error. 210 */ 211 void * 212 emalloc(size_t len) 213 { 214 void *p; 215 216 if ((p = malloc(len)) == NULL) 217 enomem(); 218 return(p); 219 } 220 221 /* 222 * estrdup -- 223 * strdup, but die on error. 42 * Make a duplicate of a string. 43 * For systems which lack this function. 224 44 */ 225 45 char * 226 estrdup(const char *str) 227 { 228 char *p; 229 230 if ((p = strdup(str)) == NULL) 231 enomem(); 232 return(p); 233 } 234 235 /* 236 * erealloc -- 237 * realloc, but die on error. 46 strdup(str) 47 const char *str; 48 { 49 size_t len; 50 51 if (str == NULL) 52 return NULL; 53 len = strlen(str) + 1; 54 if ((p = malloc(len)) == NULL) 55 return NULL; 56 57 return memcpy(p, str, len); 58 } 59 60 #endif 61 62 #if defined(sun) || defined(__hpux) || defined(__sgi) 63 64 int 65 setenv(name, value, dum) 66 const char *name; 67 const char *value; 68 int dum; 69 { 70 register char *p; 71 int len = strlen(name) + strlen(value) + 2; /* = \0 */ 72 char *ptr = (char*) malloc(len); 73 74 (void) dum; 75 76 if (ptr == NULL) 77 return -1; 78 79 p = ptr; 80 81 while (*name) 82 *p++ = *name++; 83 84 *p++ = '='; 85 86 while (*value) 87 *p++ = *value++; 88 89 *p = '\0'; 90 91 len = putenv(ptr); 92 /* free(ptr); */ 93 return len; 94 } 95 #endif 96 97 #ifdef __hpux 98 #include <sys/types.h> 99 #include <sys/param.h> 100 #include <sys/syscall.h> 101 #include <sys/signal.h> 102 #include <sys/stat.h> 103 #include <stdio.h> 104 #include <dirent.h> 105 #include <sys/time.h> 106 #include <time.h> 107 #include <unistd.h> 108 109 110 int 111 killpg(pid, sig) 112 int pid, sig; 113 { 114 return kill(-pid, sig); 115 } 116 117 void 118 srandom(seed) 119 long seed; 120 { 121 srand48(seed); 122 } 123 124 long 125 random() 126 { 127 return lrand48(); 128 } 129 130 /* turn into bsd signals */ 131 void (* 132 signal(s, a)) () 133 int s; 134 void (*a)(); 135 { 136 struct sigvec osv, sv; 137 138 (void) sigvector(s, (struct sigvec *) 0, &osv); 139 sv = osv; 140 sv.sv_handler = a; 141 #ifdef SV_BSDSIG 142 sv.sv_flags = SV_BSDSIG; 143 #endif 144 145 if (sigvector(s, &sv, (struct sigvec *) 0) == -1) 146 return (BADSIG); 147 return (osv.sv_handler); 148 } 149 150 #if !defined(BSD) && !defined(d_fileno) 151 # define d_fileno d_ino 152 #endif 153 154 #ifndef DEV_DEV_COMPARE 155 # define DEV_DEV_COMPARE(a, b) ((a) == (b)) 156 #endif 157 158 /* strrcpy(): 159 * Like strcpy, going backwards and returning the new pointer 238 160 */ 239 void * 240 erealloc(void *ptr, size_t size) 241 { 242 if ((ptr = realloc(ptr, size)) == NULL) 243 enomem(); 244 return(ptr); 245 } 246 247 /* 248 * enomem -- 249 * die when out of memory. 250 */ 251 void 252 enomem(void) 253 { 254 err(2, NULL); 255 } 256 257 /* 258 * enunlink -- 259 * Remove a file carefully, avoiding directories. 260 */ 161 static char * 162 strrcpy(ptr, str) 163 register char *ptr, *str; 164 { 165 register int len = strlen(str); 166 167 while (len) 168 *--ptr = str[--len]; 169 170 return (ptr); 171 } /* end strrcpy */ 172 173 174 char * 175 getwd(pathname) 176 char *pathname; 177 { 178 DIR *dp; 179 struct dirent *d; 180 181 struct stat st_root, st_cur, st_next, st_dotdot; 182 char pathbuf[MAXPATHLEN], nextpathbuf[MAXPATHLEN * 2]; 183 char *pathptr, *nextpathptr, *cur_name_add; 184 185 /* find the inode of root */ 186 if (stat("/", &st_root) == -1) { 187 (void) sprintf(pathname, 188 "getwd: Cannot stat \"/\" (%s)", strerror(errno)); 189 return (NULL); 190 } 191 pathbuf[MAXPATHLEN - 1] = '\0'; 192 pathptr = &pathbuf[MAXPATHLEN - 1]; 193 nextpathbuf[MAXPATHLEN - 1] = '\0'; 194 cur_name_add = nextpathptr = &nextpathbuf[MAXPATHLEN - 1]; 195 196 /* find the inode of the current directory */ 197 if (lstat(".", &st_cur) == -1) { 198 (void) sprintf(pathname, 199 "getwd: Cannot stat \".\" (%s)", strerror(errno)); 200 return (NULL); 201 } 202 nextpathptr = strrcpy(nextpathptr, "../"); 203 204 /* Descend to root */ 205 for (;;) { 206 207 /* look if we found root yet */ 208 if (st_cur.st_ino == st_root.st_ino && 209 DEV_DEV_COMPARE(st_cur.st_dev, st_root.st_dev)) { 210 (void) strcpy(pathname, *pathptr != '/' ? "/" : pathptr); 211 return (pathname); 212 } 213 214 /* open the parent directory */ 215 if (stat(nextpathptr, &st_dotdot) == -1) { 216 snprintf(pathname, sizeof(pathname), 217 "getwd: Cannot stat directory \"%s\" (%s)", 218 nextpathptr, strerror(errno)); 219 return (NULL); 220 } 221 if ((dp = opendir(nextpathptr)) == NULL) { 222 snprintf(pathname, sizeof(pathname), 223 "getwd: Cannot open directory \"%s\" (%s)", 224 nextpathptr, strerror(errno)); 225 return (NULL); 226 } 227 228 /* look in the parent for the entry with the same inode */ 229 if (DEV_DEV_COMPARE(st_dotdot.st_dev, st_cur.st_dev)) { 230 /* Parent has same device. No need to stat every member */ 231 for (d = readdir(dp); d != NULL; d = readdir(dp)) 232 if (d->d_fileno == st_cur.st_ino) 233 break; 234 } 235 else { 236 /* 237 * Parent has a different device. This is a mount point so we 238 * need to stat every member 239 */ 240 for (d = readdir(dp); d != NULL; d = readdir(dp)) { 241 if (ISDOT(d->d_name) || ISDOTDOT(d->d_name)) 242 continue; 243 (void) strcpy(cur_name_add, d->d_name); 244 if (lstat(nextpathptr, &st_next) == -1) { 245 snprintf(pathname, sizeof(pathname), "getwd: Cannot stat \"%s\" (%s)", 246 d->d_name, strerror(errno)); 247 (void) closedir(dp); 248 return (NULL); 249 } 250 /* check if we found it yet */ 251 if (st_next.st_ino == st_cur.st_ino && 252 DEV_DEV_COMPARE(st_next.st_dev, st_cur.st_dev)) 253 break; 254 } 255 } 256 if (d == NULL) { 257 (void) sprintf(pathname, "getwd: Cannot find \".\" in \"..\""); 258 (void) closedir(dp); 259 return (NULL); 260 } 261 st_cur = st_dotdot; 262 pathptr = strrcpy(pathptr, d->d_name); 263 pathptr = strrcpy(pathptr, "/"); 264 nextpathptr = strrcpy(nextpathptr, "../"); 265 (void) closedir(dp); 266 *cur_name_add = '\0'; 267 } 268 } /* end getwd */ 269 270 271 char *sys_siglist[] = { 272 "Signal 0", 273 "Hangup", /* SIGHUP */ 274 "Interrupt", /* SIGINT */ 275 "Quit", /* SIGQUIT */ 276 "Illegal instruction", /* SIGILL */ 277 "Trace/BPT trap", /* SIGTRAP */ 278 "IOT trap", /* SIGIOT */ 279 "EMT trap", /* SIGEMT */ 280 "Floating point exception", /* SIGFPE */ 281 "Killed", /* SIGKILL */ 282 "Bus error", /* SIGBUS */ 283 "Segmentation fault", /* SIGSEGV */ 284 "Bad system call", /* SIGSYS */ 285 "Broken pipe", /* SIGPIPE */ 286 "Alarm clock", /* SIGALRM */ 287 "Terminated", /* SIGTERM */ 288 "User defined signal 1", /* SIGUSR1 */ 289 "User defined signal 2", /* SIGUSR2 */ 290 "Child exited", /* SIGCLD */ 291 "Power-fail restart", /* SIGPWR */ 292 "Virtual timer expired", /* SIGVTALRM */ 293 "Profiling timer expired", /* SIGPROF */ 294 "I/O possible", /* SIGIO */ 295 "Window size changes", /* SIGWINDOW */ 296 "Stopped (signal)", /* SIGSTOP */ 297 "Stopped", /* SIGTSTP */ 298 "Continued", /* SIGCONT */ 299 "Stopped (tty input)", /* SIGTTIN */ 300 "Stopped (tty output)", /* SIGTTOU */ 301 "Urgent I/O condition", /* SIGURG */ 302 "Remote lock lost (NFS)", /* SIGLOST */ 303 "Signal 31", /* reserved */ 304 "DIL signal" /* SIGDIL */ 305 }; 306 261 307 int 262 eunlink(const char *file) 263 { 264 struct stat st; 265 266 if (lstat(file, &st) == -1) 267 return -1; 268 269 if (S_ISDIR(st.st_mode)) { 270 errno = EISDIR; 271 return -1; 272 } 273 return unlink(file); 274 } 275 276 /* 277 * Printaddr -- 278 * Print the address of a node, used as an interative function. 279 */ 280 int 281 PrintAddr(void *a, void *b __unused) 282 { 283 printf("%p ", a); 284 return 0; 285 } 308 utimes(file, tvp) 309 char *file; 310 struct timeval tvp[2]; 311 { 312 struct utimbuf t; 313 314 t.actime = tvp[0].tv_sec; 315 t.modtime = tvp[1].tv_sec; 316 return(utime(file, &t)); 317 } 318 319 320 #endif /* __hpux */ 321 322 #if defined(sun) && defined(__svr4__) 323 #include <signal.h> 324 325 /* turn into bsd signals */ 326 void (* 327 signal(s, a)) () 328 int s; 329 void (*a)(); 330 { 331 struct sigaction sa, osa; 332 333 sa.sa_handler = a; 334 sigemptyset(&sa.sa_mask); 335 sa.sa_flags = SA_RESTART; 336 337 if (sigaction(s, &sa, &osa) == -1) 338 return SIG_ERR; 339 else 340 return osa.sa_handler; 341 } 342 343 #endif
Note:
See TracChangeset
for help on using the changeset viewer.