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