github.com/bgentry/go@v0.0.0-20150121062915-6cf5a733d54d/src/lib9/await.c (about) 1 // +build !plan9 2 // +build !windows 3 4 /* 5 Plan 9 from User Space src/lib9/await.c 6 http://code.swtch.com/plan9port/src/tip/src/lib9/await.c 7 8 Copyright 2001-2007 Russ Cox. All Rights Reserved. 9 Portions Copyright 2009 The Go Authors. All Rights Reserved. 10 11 Permission is hereby granted, free of charge, to any person obtaining a copy 12 of this software and associated documentation files (the "Software"), to deal 13 in the Software without restriction, including without limitation the rights 14 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 15 copies of the Software, and to permit persons to whom the Software is 16 furnished to do so, subject to the following conditions: 17 18 The above copyright notice and this permission notice shall be included in 19 all copies or substantial portions of the Software. 20 21 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 22 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 23 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 24 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 25 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 26 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 27 THE SOFTWARE. 28 */ 29 30 #define NOPLAN9DEFINES 31 #include <u.h> 32 #include <libc.h> 33 34 #include <signal.h> 35 #include <sys/types.h> 36 #include <sys/wait.h> 37 #include <sys/time.h> 38 #include <sys/resource.h> 39 40 #ifndef WCOREDUMP /* not on Mac OS X Tiger */ 41 #define WCOREDUMP(status) 0 42 #endif 43 44 static struct { 45 int sig; 46 char *str; 47 } tab[] = { 48 SIGHUP, "hangup", 49 SIGINT, "interrupt", 50 SIGQUIT, "quit", 51 SIGILL, "sys: illegal instruction", 52 SIGTRAP, "sys: breakpoint", 53 SIGABRT, "sys: abort", 54 #ifdef SIGEMT 55 SIGEMT, "sys: emulate instruction executed", 56 #endif 57 SIGFPE, "sys: fp: trap", 58 SIGKILL, "sys: kill", 59 SIGBUS, "sys: bus error", 60 SIGSEGV, "sys: segmentation violation", 61 SIGALRM, "alarm", 62 SIGTERM, "kill", 63 SIGURG, "sys: urgent condition on socket", 64 SIGSTOP, "sys: stop", 65 SIGTSTP, "sys: tstp", 66 SIGCONT, "sys: cont", 67 SIGCHLD, "sys: child", 68 SIGTTIN, "sys: ttin", 69 SIGTTOU, "sys: ttou", 70 #ifdef SIGIO /* not on Mac OS X Tiger */ 71 SIGIO, "sys: i/o possible on fd", 72 #endif 73 SIGXCPU, "sys: cpu time limit exceeded", 74 SIGXFSZ, "sys: file size limit exceeded", 75 SIGVTALRM, "sys: virtual time alarm", 76 SIGPROF, "sys: profiling timer alarm", 77 #ifdef SIGWINCH /* not on Mac OS X Tiger */ 78 SIGWINCH, "sys: window size change", 79 #endif 80 #ifdef SIGINFO 81 SIGINFO, "sys: status request", 82 #endif 83 SIGUSR1, "sys: usr1", 84 SIGUSR2, "sys: usr2", 85 SIGPIPE, "sys: write on closed pipe", 86 }; 87 88 char* 89 _p9sigstr(int sig, char *tmp) 90 { 91 int i; 92 93 for(i=0; i<nelem(tab); i++) 94 if(tab[i].sig == sig) 95 return tab[i].str; 96 if(tmp == nil) 97 return nil; 98 sprint(tmp, "sys: signal %d", sig); 99 return tmp; 100 } 101 102 int 103 _p9strsig(char *s) 104 { 105 int i; 106 107 for(i=0; i<nelem(tab); i++) 108 if(strcmp(s, tab[i].str) == 0) 109 return tab[i].sig; 110 return 0; 111 } 112 113 static Waitmsg* 114 _wait(int pid4, int opt) 115 { 116 int pid, status, cd; 117 struct rusage ru; 118 char tmp[64]; 119 ulong u, s; 120 Waitmsg *w; 121 122 w = malloc(sizeof *w + 200); 123 if(w == nil) 124 return nil; 125 memset(w, 0, sizeof *w); 126 w->msg = (char*)&w[1]; 127 128 for(;;){ 129 /* On Linux, pid==-1 means anyone; on SunOS, it's pid==0. */ 130 if(pid4 == -1) 131 pid = wait3(&status, opt, &ru); 132 else 133 pid = wait4(pid4, &status, opt, &ru); 134 if(pid <= 0) { 135 free(w); 136 return nil; 137 } 138 u = (ulong)(ru.ru_utime.tv_sec*1000+((ru.ru_utime.tv_usec+500)/1000)); 139 s = (ulong)(ru.ru_stime.tv_sec*1000+((ru.ru_stime.tv_usec+500)/1000)); 140 w->pid = pid; 141 w->time[0] = u; 142 w->time[1] = s; 143 w->time[2] = u+s; 144 if(WIFEXITED(status)){ 145 if(status) 146 sprint(w->msg, "%d", status); 147 return w; 148 } 149 if(WIFSIGNALED(status)){ 150 cd = WCOREDUMP(status); 151 sprint(w->msg, "signal: %s", _p9sigstr(WTERMSIG(status), tmp)); 152 if(cd) 153 strcat(w->msg, " (core dumped)"); 154 return w; 155 } 156 } 157 } 158 159 Waitmsg* 160 p9wait(void) 161 { 162 return _wait(-1, 0); 163 } 164 165 Waitmsg* 166 p9waitfor(int pid) 167 { 168 return _wait(pid, 0); 169 } 170 171 Waitmsg* 172 p9waitnohang(void) 173 { 174 return _wait(-1, WNOHANG); 175 } 176 177 int 178 p9waitpid(void) 179 { 180 int status; 181 return wait(&status); 182 }