1*37da2899SCharles.Forsythimplement Tee; 2*37da2899SCharles.Forsyth 3*37da2899SCharles.Forsythinclude "sys.m"; 4*37da2899SCharles.Forsyth sys: Sys; 5*37da2899SCharles.Forsyth 6*37da2899SCharles.Forsythinclude "draw.m"; 7*37da2899SCharles.Forsyth 8*37da2899SCharles.Forsythinclude "arg.m"; 9*37da2899SCharles.Forsyth 10*37da2899SCharles.ForsythTee: module 11*37da2899SCharles.Forsyth{ 12*37da2899SCharles.Forsyth init: fn(nil: ref Draw->Context, nil: list of string); 13*37da2899SCharles.Forsyth}; 14*37da2899SCharles.Forsyth 15*37da2899SCharles.ForsythFile: adt 16*37da2899SCharles.Forsyth{ 17*37da2899SCharles.Forsyth fd: ref Sys->FD; 18*37da2899SCharles.Forsyth name: string; 19*37da2899SCharles.Forsyth}; 20*37da2899SCharles.Forsyth 21*37da2899SCharles.Forsythusage() 22*37da2899SCharles.Forsyth{ 23*37da2899SCharles.Forsyth sys->fprint(sys->fildes(2), "Usage: tee [-a] [file ...]\n"); 24*37da2899SCharles.Forsyth raise "fail:usage"; 25*37da2899SCharles.Forsyth} 26*37da2899SCharles.Forsyth 27*37da2899SCharles.Forsythinit(nil: ref Draw->Context, args: list of string) 28*37da2899SCharles.Forsyth{ 29*37da2899SCharles.Forsyth sys = load Sys Sys->PATH; 30*37da2899SCharles.Forsyth arg := load Arg Arg->PATH; 31*37da2899SCharles.Forsyth if(arg == nil) 32*37da2899SCharles.Forsyth err(sys->sprint("can't load %s: %r", Arg->PATH)); 33*37da2899SCharles.Forsyth 34*37da2899SCharles.Forsyth append := 0; 35*37da2899SCharles.Forsyth arg->init(args); 36*37da2899SCharles.Forsyth while((c := arg->opt()) != 0) 37*37da2899SCharles.Forsyth case c { 38*37da2899SCharles.Forsyth 'a' => append = 1; 39*37da2899SCharles.Forsyth * => usage(); 40*37da2899SCharles.Forsyth } 41*37da2899SCharles.Forsyth names := arg->argv(); 42*37da2899SCharles.Forsyth arg = nil; 43*37da2899SCharles.Forsyth 44*37da2899SCharles.Forsyth fd0 := sys->fildes(0); 45*37da2899SCharles.Forsyth if(fd0 == nil) 46*37da2899SCharles.Forsyth err("no standard input"); 47*37da2899SCharles.Forsyth nf := 0; 48*37da2899SCharles.Forsyth files := array[len names + 1] of ref File; 49*37da2899SCharles.Forsyth for(; names != nil; names = tl names){ 50*37da2899SCharles.Forsyth f := hd names; 51*37da2899SCharles.Forsyth fd: ref Sys->FD; 52*37da2899SCharles.Forsyth if(append){ 53*37da2899SCharles.Forsyth fd = sys->open(f, Sys->OWRITE); 54*37da2899SCharles.Forsyth if(fd != nil) 55*37da2899SCharles.Forsyth sys->seek(fd, big 0, 2); 56*37da2899SCharles.Forsyth else 57*37da2899SCharles.Forsyth fd = sys->create(f, Sys->OWRITE, 8r666); 58*37da2899SCharles.Forsyth }else 59*37da2899SCharles.Forsyth fd = sys->create(f, Sys->OWRITE, 8r666 ); 60*37da2899SCharles.Forsyth if(fd == nil) 61*37da2899SCharles.Forsyth err(sys->sprint("cannot open %s: %r", f)); 62*37da2899SCharles.Forsyth files[nf++] = ref File(fd, f); 63*37da2899SCharles.Forsyth } 64*37da2899SCharles.Forsyth files[nf++] = ref File(sys->fildes(1), "standard output"); 65*37da2899SCharles.Forsyth buf := array[Sys->ATOMICIO] of byte; 66*37da2899SCharles.Forsyth while((n := sys->read(fd0, buf, len buf)) > 0){ 67*37da2899SCharles.Forsyth for(i := 0; i < nf; i++) 68*37da2899SCharles.Forsyth if(sys->write(files[i].fd, buf, n) != n) 69*37da2899SCharles.Forsyth err(sys->sprint("error writing %s: %r", files[i].name)); 70*37da2899SCharles.Forsyth } 71*37da2899SCharles.Forsyth if(n < 0) 72*37da2899SCharles.Forsyth err(sys->sprint("read error: %r")); 73*37da2899SCharles.Forsyth} 74*37da2899SCharles.Forsyth 75*37da2899SCharles.Forsytherr(s: string) 76*37da2899SCharles.Forsyth{ 77*37da2899SCharles.Forsyth sys->fprint(sys->fildes(2), "tee: %s\n", s); 78*37da2899SCharles.Forsyth raise "fail:error"; 79*37da2899SCharles.Forsyth} 80