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