Blob


1 #define NOPLAN9DEFINES
2 #include <u.h>
3 #include <libc.h>
5 #include <signal.h>
6 #include <sys/types.h>
7 #include <sys/wait.h>
8 #include <sys/time.h>
9 #include <sys/resource.h>
11 #ifndef WCOREDUMP /* not on Mac OS X Tiger */
12 #define WCOREDUMP(status) 0
13 #endif
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 };
59 char*
60 _p9sigstr(int sig, char *tmp)
61 {
62 int i;
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 }
73 int
74 _p9strsig(char *s)
75 {
76 int i;
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 }
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;
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);
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);
120 int
121 await(char *str, int n)
123 return _await(-1, str, n, 0);
126 int
127 awaitnohang(char *str, int n)
129 return _await(-1, str, n, WNOHANG);
132 int
133 awaitfor(int pid, char *str, int n)
135 return _await(pid, str, n, 0);