rsc | bc7cb1a | 2003-11-23 18:04:47 +0000 | [diff] [blame] | 1 | #include <u.h> |
| 2 | #include <libc.h> |
| 3 | |
| 4 | char output[4096]; |
| 5 | void add(char*, ...); |
| 6 | void error(char*); |
| 7 | void notifyf(void*, char*); |
| 8 | |
| 9 | void |
| 10 | main(int argc, char *argv[]) |
| 11 | { |
| 12 | int i; |
| 13 | Waitmsg *w; |
rsc | c4097c2 | 2004-05-11 17:51:27 +0000 | [diff] [blame] | 14 | vlong t0, t1; |
rsc | bc7cb1a | 2003-11-23 18:04:47 +0000 | [diff] [blame] | 15 | long l; |
| 16 | char *p; |
| 17 | char err[ERRMAX]; |
| 18 | |
| 19 | if(argc <= 1){ |
| 20 | fprint(2, "usage: time command\n"); |
| 21 | exits("usage"); |
| 22 | } |
| 23 | |
rsc | c4097c2 | 2004-05-11 17:51:27 +0000 | [diff] [blame] | 24 | t0 = nsec(); |
rsc | bc7cb1a | 2003-11-23 18:04:47 +0000 | [diff] [blame] | 25 | switch(fork()){ |
| 26 | case -1: |
| 27 | error("fork"); |
| 28 | case 0: |
| 29 | exec(argv[1], &argv[1]); |
| 30 | if(argv[1][0] != '/' && strncmp(argv[1], "./", 2) && |
| 31 | strncmp(argv[1], "../", 3)){ |
| 32 | sprint(output, "/bin/%s", argv[1]); |
| 33 | exec(output, &argv[1]); |
| 34 | } |
| 35 | error(argv[1]); |
| 36 | } |
| 37 | |
| 38 | notify(notifyf); |
| 39 | |
| 40 | loop: |
| 41 | w = wait(); |
rsc | c4097c2 | 2004-05-11 17:51:27 +0000 | [diff] [blame] | 42 | t1 = nsec(); |
rsc | bc7cb1a | 2003-11-23 18:04:47 +0000 | [diff] [blame] | 43 | if(w == nil){ |
rsc | c4097c2 | 2004-05-11 17:51:27 +0000 | [diff] [blame] | 44 | rerrstr(err, sizeof err); |
rsc | bc7cb1a | 2003-11-23 18:04:47 +0000 | [diff] [blame] | 45 | if(strcmp(err, "interrupted") == 0) |
| 46 | goto loop; |
| 47 | error("wait"); |
| 48 | } |
| 49 | l = w->time[0]; |
| 50 | add("%ld.%.2ldu", l/1000, (l%1000)/10); |
| 51 | l = w->time[1]; |
| 52 | add("%ld.%.2lds", l/1000, (l%1000)/10); |
rsc | c4097c2 | 2004-05-11 17:51:27 +0000 | [diff] [blame] | 53 | l = (t1-t0)/1000000; |
rsc | bc7cb1a | 2003-11-23 18:04:47 +0000 | [diff] [blame] | 54 | add("%ld.%.2ldr", l/1000, (l%1000)/10); |
| 55 | add("\t"); |
| 56 | for(i=1; i<argc; i++){ |
| 57 | add("%s", argv[i], 0); |
| 58 | if(i>4){ |
| 59 | add("..."); |
| 60 | break; |
| 61 | } |
| 62 | } |
| 63 | if(w->msg[0]){ |
| 64 | p = utfrune(w->msg, ':'); |
| 65 | if(p && p[1]) |
| 66 | p++; |
| 67 | else |
| 68 | p = w->msg; |
| 69 | add(" # status=%s", p); |
| 70 | } |
| 71 | fprint(2, "%s\n", output); |
| 72 | exits(w->msg); |
| 73 | } |
| 74 | |
| 75 | void |
| 76 | add(char *a, ...) |
| 77 | { |
| 78 | static int beenhere=0; |
| 79 | va_list arg; |
| 80 | |
| 81 | if(beenhere) |
| 82 | strcat(output, " "); |
| 83 | va_start(arg, a); |
| 84 | vseprint(output+strlen(output), output+sizeof(output), a, arg); |
| 85 | va_end(arg); |
| 86 | beenhere++; |
| 87 | } |
| 88 | |
| 89 | void |
| 90 | error(char *s) |
| 91 | { |
| 92 | |
| 93 | fprint(2, "time: %s: %r\n", s); |
| 94 | exits(s); |
| 95 | } |
| 96 | |
| 97 | void |
| 98 | notifyf(void *a, char *s) |
| 99 | { |
| 100 | USED(a); |
| 101 | if(strcmp(s, "interrupt") == 0) |
| 102 | noted(NCONT); |
| 103 | noted(NDFLT); |
| 104 | } |