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