xref: /inferno-os/appl/cmd/B.b (revision 37da2899f40661e3e9631e497da8dc59b971cbd0)
1implement B;
2
3include "sys.m";
4include "draw.m";
5include "workdir.m";
6
7FD: import Sys;
8Context: import Draw;
9
10B: module
11{
12	init:	fn(nil: ref Context, argv: list of string);
13};
14
15sys: Sys;
16stderr: ref FD;
17wkdir: string;
18
19init(nil: ref Context, argv: list of string)
20{
21	sys = load Sys Sys->PATH;
22	stderr = sys->fildes(2);
23
24	if(len argv < 2) {
25		sys->fprint(stderr, "Usage: B file ...\n");
26		return;
27	}
28	argv = tl argv;
29
30	cmd := "exec B ";
31	while(argv != nil) {
32		f := hd argv;
33		if(len f > 0 && f[0] != '/' && f[0] != '-')
34			f = wd() + f;
35		cmd += "/usr/inferno"+f;
36		argv = tl argv;
37		if(argv != nil)
38			cmd += " ";
39	}
40	cfd := sys->open("/cmd/clone", sys->ORDWR);
41	if(cfd == nil) {
42		sys->fprint(stderr, "B: open /cmd/clone: %r\n");
43		return;
44	}
45
46	buf := array[32] of byte;
47	n := sys->read(cfd, buf, len buf);
48	if(n <= 0) {
49		sys->fprint(stderr, "B: read /cmd/#/ctl: %r\n");
50		return;
51	}
52	dir := "/cmd/"+string buf[0:n];
53
54	# Start the Command
55	n = sys->fprint(cfd, "%s", cmd);
56	if(n <= 0) {
57		sys->fprint(stderr, "B: exec: %r\n");
58		return;
59	}
60
61	io := sys->open(dir+"/data", sys->ORDWR);
62	if(io == nil) {
63		sys->fprint(stderr, "B: open /cmd/#/data: %r\n");
64		return;
65	}
66
67	sys->pctl(sys->NEWPGRP, nil);
68	copy(io, sys->fildes(1), nil);
69}
70
71wd(): string
72{
73	if(wkdir != nil)
74		return wkdir;
75
76	gwd := load Workdir Workdir->PATH;
77
78	wkdir = gwd->init();
79	if(wkdir == nil) {
80		sys->fprint(stderr, "B: can't get working dir: %r");
81		exit;
82	}
83	wkdir = wkdir+"/";
84	return wkdir;
85}
86
87copy(f, t: ref FD, c: chan of int)
88{
89	if(c != nil)
90		c <-= sys->pctl(0, nil);
91
92	buf := array[8192] of byte;
93	for(;;) {
94		r := sys->read(f, buf, len buf);
95		if(r <= 0)
96			break;
97		w := sys->write(t, buf, r);
98		if(w != r)
99			break;
100	}
101}
102
103kill(pid: int)
104{
105	fd := sys->open("/prog/"+string pid+"/ctl", sys->OWRITE);
106	sys->fprint(fd, "kill");
107}
108