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