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