1# 2# stream data from files 3# 4# Copyright © 2000 Vita Nuova Limited. All rights reserved. 5# 6 7implement Stream; 8 9include "sys.m"; 10 sys: Sys; 11include "draw.m"; 12 13Stream: module 14{ 15 init: fn(nil: ref Draw->Context, argv: list of string); 16}; 17 18stderr: ref Sys->FD; 19 20usage() 21{ 22 sys->fprint(stderr, "Usage: stream [-a] [-b bufsize] file1 [file2]\n"); 23 fail("usage"); 24} 25 26init(nil: ref Draw->Context, argv: list of string) 27{ 28 sys = load Sys Sys->PATH; 29 stderr = sys->fildes(2); 30 31 bsize := 0; 32 sync := chan of int; 33 if(argv != nil) 34 argv = tl argv; 35 for(; argv != nil && len hd argv && (s := hd argv)[0] == '-' && len s > 1; argv = tl argv) 36 case s[1] { 37 'b' => 38 if(len s > 2) 39 bsize = int s[2:]; 40 else if((argv = tl argv) != nil) 41 bsize = int hd argv; 42 else 43 usage(); 44 'a' => 45 sync = nil; 46 * => 47 usage(); 48 } 49 if(bsize <= 0 || bsize > 2*1024*1024) 50 bsize = Sys->ATOMICIO; 51 argc := len argv; 52 if(argc < 1) 53 usage(); 54 55 if(argc > 1){ 56 f1 := eopen(hd argv, Sys->ORDWR); 57 f2 := eopen(hd tl argv, Sys->ORDWR); 58 spawn stream(f1, f2, bsize, sync); 59 spawn stream(f2, f1, bsize, sync); 60 }else{ 61 f2 := sys->fildes(1); 62 if(f2 == nil) { 63 sys->fprint(stderr, "stream: can't access standard output: %r\n"); 64 fail("stdout"); 65 } 66 f1 := eopen(hd argv, Sys->OREAD); 67 spawn stream(f1, f2, bsize, sync); 68 } 69 if(sync != nil){ # count them back in 70 <-sync; 71 if(argc > 1) 72 <-sync; 73 } 74} 75 76stream(source: ref Sys->FD, sink: ref Sys->FD, bufsize: int, sync: chan of int) 77{ 78 if(sys->stream(source, sink, bufsize) < 0) 79 sys->fprint(stderr, "stream: error streaming data: %r\n"); 80 if(sync != nil) 81 sync <-= 1; 82} 83 84eopen(name: string, mode: int): ref Sys->FD 85{ 86 fd := sys->open(name, mode); 87 if(fd == nil){ 88 sys->fprint(stderr, "stream: can't open %s: %r\n", name); 89 fail("open"); 90 } 91 return fd; 92} 93 94fail(s: string) 95{ 96 raise "fail:"+s; 97} 98