aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/time.c
blob: 3b52216b96def02205504b58ef635704f226f9c2 (plain)
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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
#include <u.h>
#include <libc.h>

char	output[4096];
void	add(char*, ...);
void	error(char*);
void	notifyf(void*, char*);

void
main(int argc, char *argv[])
{
	int i;
	Waitmsg *w;
	vlong t0, t1;
	long l;
	char *p;
	char err[ERRMAX];

	if(argc <= 1){
		fprint(2, "usage: time command\n");
		exits("usage");
	}

	t0 = nsec();
	switch(fork()){
	case -1:
		error("fork");
	case 0:
		exec(argv[1], &argv[1]);
		if(argv[1][0] != '/' && strncmp(argv[1], "./", 2) &&
		   strncmp(argv[1], "../", 3)){
			sprint(output, "/bin/%s", argv[1]);
			exec(output, &argv[1]);
		}
		error(argv[1]);
	}

	notify(notifyf);

    loop:
	w = wait();
	t1 = nsec();
	if(w == nil){
		rerrstr(err, sizeof err);
		if(strcmp(err, "interrupted") == 0)
			goto loop;
		error("wait");
	}
	l = w->time[0];
	add("%ld.%.2ldu", l/1000, (l%1000)/10);
	l = w->time[1];
	add("%ld.%.2lds", l/1000, (l%1000)/10);
	l = (t1-t0)/1000000;
	add("%ld.%.2ldr", l/1000, (l%1000)/10);
	add("\t");
	for(i=1; i<argc; i++){
		add("%s", argv[i], 0);
		if(i>4){
			add("...");
			break;
		}
	}
	if(w->msg[0]){
		p = utfrune(w->msg, ':');
		if(p && p[1])
			p++;
		else
			p = w->msg;
		add(" # status=%s", p);
	}
	fprint(2, "%s\n", output);
	exits(w->msg);
}

void
add(char *a, ...)
{
	static int beenhere=0;
	va_list arg;

	if(beenhere)
		strcat(output, " ");
	va_start(arg, a);
	vseprint(output+strlen(output), output+sizeof(output), a, arg);
	va_end(arg);
	beenhere++;
}

void
error(char *s)
{

	fprint(2, "time: %s: %r\n", s);
	exits(s);
}

void
notifyf(void *a, char *s)
{
	USED(a);
	if(strcmp(s, "interrupt") == 0)
		noted(NCONT);
	noted(NDFLT);
}