await.c (2937B)
1 #define NOPLAN9DEFINES 2 #include <u.h> 3 #include <libc.h> 4 5 #include <signal.h> 6 #include <sys/types.h> 7 #include <sys/wait.h> 8 #include <sys/time.h> 9 #include <sys/resource.h> 10 11 #ifndef WCOREDUMP /* not on Mac OS X Tiger */ 12 #define WCOREDUMP(status) 0 13 #endif 14 15 static struct { 16 int sig; 17 char *str; 18 } tab[] = { 19 SIGHUP, "hangup", 20 SIGINT, "interrupt", 21 SIGQUIT, "quit", 22 SIGILL, "sys: illegal instruction", 23 SIGTRAP, "sys: breakpoint", 24 SIGABRT, "sys: abort", 25 #ifdef SIGEMT 26 SIGEMT, "sys: emulate instruction executed", 27 #endif 28 SIGFPE, "sys: fp: trap", 29 SIGKILL, "sys: kill", 30 SIGBUS, "sys: bus error", 31 SIGSEGV, "sys: segmentation violation", 32 SIGALRM, "alarm", 33 SIGTERM, "kill", 34 SIGURG, "sys: urgent condition on socket", 35 SIGSTOP, "sys: stop", 36 SIGTSTP, "sys: tstp", 37 SIGCONT, "sys: cont", 38 SIGCHLD, "sys: child", 39 SIGTTIN, "sys: ttin", 40 SIGTTOU, "sys: ttou", 41 #ifdef SIGIO /* not on Mac OS X Tiger */ 42 SIGIO, "sys: i/o possible on fd", 43 #endif 44 SIGXCPU, "sys: cpu time limit exceeded", 45 SIGXFSZ, "sys: file size limit exceeded", 46 SIGVTALRM, "sys: virtual time alarm", 47 SIGPROF, "sys: profiling timer alarm", 48 #ifdef SIGWINCH /* not on Mac OS X Tiger */ 49 SIGWINCH, "sys: window size change", 50 #endif 51 #ifdef SIGINFO 52 SIGINFO, "sys: status request", 53 #endif 54 SIGUSR1, "sys: usr1", 55 SIGUSR2, "sys: usr2", 56 SIGPIPE, "sys: write on closed pipe", 57 }; 58 59 char* 60 _p9sigstr(int sig, char *tmp) 61 { 62 int i; 63 64 for(i=0; i<nelem(tab); i++) 65 if(tab[i].sig == sig) 66 return tab[i].str; 67 if(tmp == nil) 68 return nil; 69 sprint(tmp, "sys: signal %d", sig); 70 return tmp; 71 } 72 73 int 74 _p9strsig(char *s) 75 { 76 int i; 77 78 for(i=0; i<nelem(tab); i++) 79 if(strcmp(s, tab[i].str) == 0) 80 return tab[i].sig; 81 return 0; 82 } 83 84 static int 85 _await(int pid4, char *str, int n, int opt) 86 { 87 int pid, status, cd; 88 struct rusage ru; 89 char buf[128], tmp[64]; 90 ulong u, s; 91 92 for(;;){ 93 /* On Linux, pid==-1 means anyone; on SunOS, it's pid==0. */ 94 if(pid4 == -1) 95 pid = wait3(&status, opt, &ru); 96 else 97 pid = wait4(pid4, &status, opt, &ru); 98 if(pid <= 0) 99 return -1; 100 u = ru.ru_utime.tv_sec*1000+((ru.ru_utime.tv_usec+500)/1000); 101 s = ru.ru_stime.tv_sec*1000+((ru.ru_stime.tv_usec+500)/1000); 102 if(WIFEXITED(status)){ 103 status = WEXITSTATUS(status); 104 if(status) 105 snprint(buf, sizeof buf, "%d %lud %lud %lud %d", pid, u, s, u+s, status); 106 else 107 snprint(buf, sizeof buf, "%d %lud %lud %lud ''", pid, u, s, u+s, status); 108 strecpy(str, str+n, buf); 109 return strlen(str); 110 } 111 if(WIFSIGNALED(status)){ 112 cd = WCOREDUMP(status); 113 snprint(buf, sizeof buf, "%d %lud %lud %lud 'signal: %s%s'", pid, u, s, u+s, _p9sigstr(WTERMSIG(status), tmp), cd ? " (core dumped)" : ""); 114 strecpy(str, str+n, buf); 115 return strlen(str); 116 } 117 } 118 } 119 120 int 121 await(char *str, int n) 122 { 123 return _await(-1, str, n, 0); 124 } 125 126 int 127 awaitnohang(char *str, int n) 128 { 129 return _await(-1, str, n, WNOHANG); 130 } 131 132 int 133 awaitfor(int pid, char *str, int n) 134 { 135 return _await(pid, str, n, 0); 136 } 137