await.c - 9base - revived minimalist port of Plan 9 userland to Unix | |
git clone git://git.suckless.org/9base | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
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)/1… | |
101 s = ru.ru_stime.tv_sec*1000+((ru.ru_stime.tv_usec+500)/1… | |
102 if(WIFEXITED(status)){ | |
103 status = WEXITSTATUS(status); | |
104 if(status) | |
105 snprint(buf, sizeof buf, "%d %lud %lud %… | |
106 else | |
107 snprint(buf, sizeof buf, "%d %lud %lud %… | |
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 'sig… | |
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 |