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