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