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#define FOR_timeout
29#include "toys.h"
30
31GLOBALS(
32 char *s, *k;
33
34 int nextsig;
35 pid_t pid;
36 struct timeval ktv;
37 struct itimerval itv;
38)
39
40static void handler(int i)
41{
42 if (FLAG(v))
43 fprintf(stderr, "timeout pid %d signal %d\n", TT.pid, TT.nextsig);
44
45 kill(TT.pid, TT.nextsig);
46
47 if (TT.k) {
48 TT.k = 0;
49 TT.nextsig = SIGKILL;
50 xsignal(SIGALRM, handler);
51 TT.itv.it_value = TT.ktv;
52 setitimer(ITIMER_REAL, &TT.itv, (void *)toybuf);
53 }
54}
55
56
57
58void xparsetimeval(char *s, struct timeval *tv)
59{
60 long ll;
61
62 tv->tv_sec = xparsetime(s, 6, &ll);
63 tv->tv_usec = ll;
64}
65
66void timeout_main(void)
67{
68 toys.exitval = 125;
69
70
71 xparsetimeval(*toys.optargs, &TT.itv.it_value);
72 if (TT.k) xparsetimeval(TT.k, &TT.ktv);
73
74 TT.nextsig = SIGTERM;
75 if (TT.s && -1 == (TT.nextsig = sig_to_num(TT.s)))
76 error_exit("bad -s: '%s'", TT.s);
77
78 if (!FLAG(foreground)) setpgid(0, 0);
79
80 if (!(TT.pid = XVFORK())) xexec(toys.optargs+1);
81 else {
82 int status;
83
84 xsignal(SIGALRM, handler);
85 setitimer(ITIMER_REAL, &TT.itv, (void *)toybuf);
86
87 while (-1 == waitpid(TT.pid, &status, 0) && errno == EINTR);
88 if (WIFEXITED(status)) toys.exitval = WEXITSTATUS(status);
89 else if (WTERMSIG(status)==SIGKILL) toys.exitval = 137;
90 else toys.exitval = FLAG(preserve_status) ? 128+WTERMSIG(status) : 124;
91 }
92}
93