blob: 7d0ca916161abfcbd4246ef2dbe99d3abfe58920 [file] [log] [blame]
rscfd04aac2003-11-23 18:12:54 +00001#define NOPLAN9DEFINES
2#include <u.h>
3#include <libc.h>
4
rscb2cfc4e2003-09-30 17:47:41 +00005#include <signal.h>
6#include <sys/types.h>
rsc912fba92003-11-24 22:39:06 +00007#include <sys/time.h>
rscb2cfc4e2003-09-30 17:47:41 +00008#include <sys/resource.h>
9#include <sys/wait.h>
rscb2cfc4e2003-09-30 17:47:41 +000010
11static struct {
12 int sig;
13 char *str;
14} tab[] = {
15 SIGHUP, "hangup",
16 SIGINT, "interrupt",
17 SIGQUIT, "quit",
rscb4223cd2005-01-04 22:18:13 +000018 SIGILL, "sys: illegal instruction",
19 SIGTRAP, "sys: breakpoint",
rscb2cfc4e2003-09-30 17:47:41 +000020 SIGABRT, "sys: abort",
rscd2c4ee92003-11-24 00:43:41 +000021#ifdef SIGEMT
rscb2cfc4e2003-09-30 17:47:41 +000022 SIGEMT, "sys: emulate instruction executed",
rscd2c4ee92003-11-24 00:43:41 +000023#endif
rscb2cfc4e2003-09-30 17:47:41 +000024 SIGFPE, "sys: fp: trap",
25 SIGKILL, "sys: kill",
26 SIGBUS, "sys: bus error",
27 SIGSEGV, "sys: segmentation violation",
28 SIGALRM, "alarm",
29 SIGTERM, "kill",
30 SIGURG, "sys: urgent condition on socket",
31 SIGSTOP, "sys: stop",
32 SIGTSTP, "sys: tstp",
33 SIGCONT, "sys: cont",
34 SIGCHLD, "sys: child",
35 SIGTTIN, "sys: ttin",
36 SIGTTOU, "sys: ttou",
37 SIGIO, "sys: i/o possible on fd",
38 SIGXCPU, "sys: cpu time limit exceeded",
39 SIGXFSZ, "sys: file size limit exceeded",
40 SIGVTALRM, "sys: virtual time alarm",
41 SIGPROF, "sys: profiling timer alarm",
42 SIGWINCH, "sys: window size change",
rsc1c253ce2003-11-23 19:49:17 +000043#ifdef SIGINFO
rscb2cfc4e2003-09-30 17:47:41 +000044 SIGINFO, "sys: status request",
rsc1c253ce2003-11-23 19:49:17 +000045#endif
rscb2cfc4e2003-09-30 17:47:41 +000046 SIGUSR1, "sys: usr1",
47 SIGUSR2, "sys: usr2",
rsc32f69c32003-12-11 17:48:38 +000048 SIGPIPE, "sys: write on closed pipe",
rscb2cfc4e2003-09-30 17:47:41 +000049};
50
rscfd04aac2003-11-23 18:12:54 +000051char*
rscb2cfc4e2003-09-30 17:47:41 +000052_p9sigstr(int sig, char *tmp)
53{
54 int i;
55
56 for(i=0; i<nelem(tab); i++)
57 if(tab[i].sig == sig)
58 return tab[i].str;
rsc3a9dccd2004-04-02 22:57:49 +000059 if(tmp == nil)
60 return nil;
rscb2cfc4e2003-09-30 17:47:41 +000061 sprint(tmp, "sys: signal %d", sig);
62 return tmp;
63}
64
rscfd04aac2003-11-23 18:12:54 +000065int
rscb2cfc4e2003-09-30 17:47:41 +000066_p9strsig(char *s)
67{
68 int i;
69
70 for(i=0; i<nelem(tab); i++)
71 if(strcmp(s, tab[i].str) == 0)
72 return tab[i].sig;
73 return 0;
74}
rscb2cfc4e2003-09-30 17:47:41 +000075
rsc5a8e63b2004-02-29 22:10:26 +000076static int
rsc03417612004-12-27 19:11:21 +000077_await(int pid4, char *str, int n, int opt)
rscb2cfc4e2003-09-30 17:47:41 +000078{
79 int pid, status, cd;
80 struct rusage ru;
81 char buf[128], tmp[64];
82 ulong u, s;
83
84 for(;;){
rsc005a85f2005-01-07 08:02:54 +000085 /* On Linux, pid==-1 means anyone; on SunOS, it's pid==0. */
86 if(pid4 == -1)
87 pid = wait3(&status, opt, &ru);
88 else
89 pid = wait4(pid4, &status, opt, &ru);
rsc5a8e63b2004-02-29 22:10:26 +000090 if(pid <= 0)
rscb2cfc4e2003-09-30 17:47:41 +000091 return -1;
92 u = ru.ru_utime.tv_sec*1000+((ru.ru_utime.tv_usec+500)/1000);
93 s = ru.ru_stime.tv_sec*1000+((ru.ru_stime.tv_usec+500)/1000);
94 if(WIFEXITED(status)){
95 status = WEXITSTATUS(status);
96 if(status)
rscfd04aac2003-11-23 18:12:54 +000097 snprint(buf, sizeof buf, "%d %lud %lud %lud %d", pid, u, s, u+s, status);
rscb2cfc4e2003-09-30 17:47:41 +000098 else
rscfd04aac2003-11-23 18:12:54 +000099 snprint(buf, sizeof buf, "%d %lud %lud %lud ''", pid, u, s, u+s, status);
rscb2cfc4e2003-09-30 17:47:41 +0000100 strecpy(str, str+n, buf);
101 return strlen(str);
102 }
103 if(WIFSIGNALED(status)){
104 cd = WCOREDUMP(status);
rsc99834d12004-10-22 17:11:47 +0000105 snprint(buf, sizeof buf, "%d %lud %lud %lud 'signal: %s%s'", pid, u, s, u+s, _p9sigstr(WTERMSIG(status), tmp), cd ? " (core dumped)" : "");
rscb2cfc4e2003-09-30 17:47:41 +0000106 strecpy(str, str+n, buf);
107 return strlen(str);
108 }
109 }
110}
rsc5a8e63b2004-02-29 22:10:26 +0000111
112int
113await(char *str, int n)
114{
rsc03417612004-12-27 19:11:21 +0000115 return _await(-1, str, n, 0);
rsc5a8e63b2004-02-29 22:10:26 +0000116}
117
118int
119awaitnohang(char *str, int n)
120{
rsc03417612004-12-27 19:11:21 +0000121 return _await(-1, str, n, WNOHANG);
122}
123
124int
125awaitfor(int pid, char *str, int n)
126{
127 return _await(pid, str, n, 0);
rsc5a8e63b2004-02-29 22:10:26 +0000128}
129