#include <u.h>
#include <libc.h>
-int cpid;
-
void
usage(void)
{
- fprint(2,"usage: alarm time path arg ...\n");
+ fprint(2,"usage: %s time command [ arg ... ]\n", argv0);
exits("usage");
}
-static int
-notefun(void *a, char *msg)
+static void
+catch(void *, char *msg)
{
- USED(a);
- postnote(PNGROUP, cpid, msg);
- if(strcmp(msg, "alarm") == 0){
- return 1;
- }
- return 0;
+ postnote(PNGROUP, getpid(), msg);
+ noted(NDFLT);
}
void
main(int argc, char *argv[])
{
- char *cmd;
- int t;
- ARGBEGIN{
- default: usage();
- }ARGEND
-
- if(*argv == nil)
- usage();
+ char buf[1024], *p, *q;
+ Waitmsg *w;
+ long n, t;
- t = atoi(argv[0]);
- argv++;
- if(*argv ==nil)
+ argv0 = argv[0];
+ if(argc < 3)
usage();
- cmd = argv[0];
- /* cmd must be a path, absolute or relative */
- if(*cmd != '/' && strcmp(cmd, "./") != 0 && strcmp(cmd, "../") != 0)
+ n = strtol(argv[1], &p, 10);
+ if(n < 0)
usage();
- argv[0] = strrchr(cmd,'/');
- atnotify(notefun,1);
- alarm(t*1000);
-
- switch((cpid = rfork(RFFDG|RFREND|RFPROC|RFMEM|RFNOTEG))){
+ t = n * 1000;
+ if(*p++ == '.' && (n = strtol(p, &q, 10)) > 0){
+ switch(q - p){
+ case 0:
+ break;
+ case 1:
+ n *= 100;
+ break;
+ case 2:
+ n *= 10;
+ break;
+ default:
+ p[3] = 0;
+ n = strtol(p, 0, 10);
+ break;
+ }
+ t += n;
+ }
+ rfork(RFNOTEG);
+ switch(rfork(RFFDG|RFREND|RFPROC|RFMEM)){
case -1:
- sysfatal("rfork: %r");
+ sysfatal("%r");
case 0: /* child */
- exec(cmd,argv);
- default: /* parent */
- break;
+ exec(argv[2], &argv[2]);
+ if(argv[2][0] != '/' && strncmp(argv[2], "./", 2) &&
+ strncmp(argv[2], "../", 3)){
+ snprint(buf, sizeof(buf), "/bin/%s", argv[2]);
+ exec(argv[2] = buf, &argv[2]);
+ }
+ sysfatal("%s: %r", argv[2]);
}
- waitpid();
+ notify(catch);
+ alarm(t);
+ if(w = wait())
+ exits(w->msg);
+ exits("alarm");
}
-