summaryrefslogtreecommitdiff
path: root/appl/cmd/time.b
blob: b4fba1593fa2ddec4b61888bfdbfff4d231f7cec (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
implement Time;

include "sys.m";
include "draw.m";
include "sh.m";

FD: import Sys;
Context: import Draw;

Time: module
{
	init:	fn(ctxt: ref Context, argv: list of string);
};

sys: Sys;
stderr, waitfd: ref FD;

init(ctxt: ref Context, argv: list of string)
{
	sys = load Sys Sys->PATH;

	stderr = sys->fildes(2);

	waitfd = sys->open("#p/"+string sys->pctl(0, nil)+"/wait", sys->OREAD);
	if(waitfd == nil){
		sys->fprint(stderr, "time: open wait: %r\n");
		return;
	}

	argv = tl argv;

	if(argv == nil) {
		sys->fprint(stderr, "usage: time cmd ...\n");
		return;
	}

	file := hd argv;

	if(len file<4 || file[len file-4:]!=".dis")
		file += ".dis";

	t0 := sys->millisec();

	c := load Command file;
	if(c == nil) {
		err := sys->sprint("%r");
		if(1){
			c = load Command "/dis/"+file;
			if(c == nil)
				err = sys->sprint("%r");
		}
		if(c == nil) {
			sys->fprint(stderr, "time: %s: %s\n", hd argv, err);
			return;
		}
	}

	t1 := sys->millisec();

	pidc := chan of int;

	spawn cmd(ctxt, c, pidc, argv);
	waitfor(<-pidc);

	t2 := sys->millisec();

	f1 := real (t1 - t0) /1000.;
	f2 := real (t2 - t1) /1000.;
	sys->fprint(stderr, "%.4gl %.4gr %.4gt\n", f1, f2, f1+f2);
}

cmd(ctxt: ref Context, c: Command, pidc: chan of int, argv: list of string)
{
	pidc <-= sys->pctl(0, nil);
	c->init(ctxt, argv);
}

waitfor(pid: int)
{
	buf := array[sys->WAITLEN] of byte;
	status := "";
	for(;;){
		n := sys->read(waitfd, buf, len buf);
		if(n < 0) {
			sys->fprint(stderr, "sh: read wait: %r\n");
			return;
		}
		status = string buf[0:n];
		if(status[len status-1] != ':')
			sys->fprint(stderr, "%s\n", status);
		who := int status;
		if(who != 0) {
			if(who == pid)
				return;
		}
	}
}