xref: /inferno-os/appl/cmd/read.b (revision 37da2899f40661e3e9631e497da8dc59b971cbd0)
1implement Read;
2include "sys.m";
3	sys: Sys;
4include "draw.m";
5
6Read: module {
7	init: fn(nil: ref Draw->Context, argv: list of string);
8};
9
10usage()
11{
12	sys->fprint(sys->fildes(2), "usage: read [-[ero] offset] count\n");
13	raise "fail:usage";
14}
15
16init(nil: ref Draw->Context, argv: list of string)
17{
18	sys = load Sys Sys->PATH;
19	# usage: read [-[ero] offset] count
20	count := Sys->ATOMICIO;
21	offset := big 0;
22	seeking := -1;
23	if (argv != nil)
24		argv = tl argv;
25	if (argv != nil && hd argv != nil && (hd argv)[0] == '-') {
26		if (tl argv == nil)
27			usage();
28		case hd argv {
29		"-o" =>
30			seeking = Sys->SEEKSTART;
31		"-e" =>
32			seeking = Sys->SEEKEND;
33		"-r" =>
34			seeking = Sys->SEEKRELA;
35		* =>
36			usage();
37		}
38		offset = big hd tl argv;
39		argv = tl tl argv;
40	}
41	if (argv != nil) {
42		if (tl argv != nil)
43			usage();
44		count = int hd argv;
45	}
46	fd := sys->fildes(0);
47	if (seeking != -1)
48		sys->seek(fd, offset, seeking);
49	if (count == 0)
50		return;
51	buf := array[count] of byte;
52	n := sys->read(fd, buf, len buf);
53	if (n > 0)
54		sys->write(sys->fildes(1), buf, n);
55	else {
56		if (n == -1) {
57			sys->fprint(sys->fildes(2), "read: read error: %r\n");
58			raise "fail:error";
59		}
60		raise "fail:eof";
61	}
62}
63