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