]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/alarm.c
etheriwl: don't break controller on command flush timeout
[plan9front.git] / sys / src / cmd / alarm.c
1 /*
2 *       alarm
3 *
4 *       you may think some rc script can be same effect
5 *       I did but I realized rc script does not work cleanly.
6 *       The bellowing has a problem. so I wrote in C
7 *       -Kenar-
8 *       
9 *       #!/bin/rc
10 *       if(~ $* 0 1)
11 *               echo usage: alarm time command arg ...
12 *       rfork e
13 *       t=$1
14 *       shift
15 *       c=$*
16 *       {       sleep $t;
17 *               if(test -e /proc/$pid)
18 *                       echo alarm >/proc/$pid/note
19 *       }&
20 *       exec $c
21 *
22 */
23
24 #include <u.h>
25 #include <libc.h>
26
27 void
28 usage(void)
29 {
30         fprint(2,"usage: %s time command [ arg ... ]\n", argv0);
31         exits("usage");
32 }
33
34 static void
35 catch(void *, char *msg)
36 {
37         postnote(PNGROUP, getpid(), msg);
38         noted(NDFLT);
39 }
40
41 void
42 main(int argc, char *argv[])
43 {
44         char buf[1024], *p, *q;
45         Waitmsg *w;
46         long n, t;
47
48         argv0 = argv[0];
49         if(argc < 3)
50                 usage();
51         n = strtol(argv[1], &p, 10);
52         if(n < 0)
53                 usage();
54         t = n * 1000;
55         if(*p++ == '.' && (n = strtol(p, &q, 10)) > 0){
56                 switch(q - p){
57                 case 0:
58                         break;
59                 case 1:
60                         n *= 100;
61                         break;
62                 case 2:
63                         n *= 10;
64                         break;
65                 default:
66                         p[3] = 0;
67                         n = strtol(p, 0, 10);
68                         break;
69                 }
70                 t += n;
71         }
72         rfork(RFNOTEG);
73         switch(rfork(RFFDG|RFREND|RFPROC|RFMEM)){
74         case -1:
75                 sysfatal("%r");
76         case 0: /* child */
77                 exec(argv[2], &argv[2]);
78                 if(argv[2][0] != '/' && strncmp(argv[2], "./", 2) &&
79                    strncmp(argv[2], "../", 3)){
80                         snprint(buf, sizeof(buf), "/bin/%s", argv[2]);
81                         exec(argv[2] = buf, &argv[2]);
82                 }
83                 sysfatal("%s: %r", argv[2]);
84         }
85         notify(catch);
86         alarm(t);
87         if(w = wait())
88                 exits(w->msg);
89         exits("alarm");
90 }