xref: /inferno-os/appl/cmd/stream.b (revision 88388bd46774cb3b4dfaaa02473a85d36d9d76dc)
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