hautils

[hare] Set of POSIX utilities
Log | Files | Refs | README | LICENSE

tee.ha (1138B)


      1 use fmt;
      2 use fs;
      3 use getopt;
      4 use io;
      5 use main;
      6 use os;
      7 
      8 export fn utilmain() (main::error | void) = {
      9 	const cmd = getopt::parse(os::args,
     10 		"read from standard input and write to standard output and files",
     11 		('a', "append the output to the files"),
     12 		('i', "ignore the SIGINT signal"),
     13 		"file...",
     14 	);
     15 	defer getopt::finish(&cmd);
     16 
     17 	let flags = fs::flag::WRONLY;
     18 	for (let i = 0z; i < len(cmd.opts); i += 1) {
     19 		const opt = cmd.opts[i];
     20 		switch (opt.0) {
     21 		case 'a' =>
     22 			flags |= fs::flag::APPEND;
     23 		case 'i' =>
     24 			abort("TODO: Ignore SIGINT");
     25 		case =>
     26 			abort(); // Invariant
     27 		};
     28 	};
     29 
     30 	let source = os::stdin;
     31 	let files: []io::file = [];
     32 	defer {
     33 		for (let i = 0z; i < len(files); i += 1) {
     34 			io::close(files[i])!;
     35 		};
     36 		free(files);
     37 	};
     38 
     39 	for (let i = 0z; i < len(cmd.args); i += 1) {
     40 		const file = match (os::create(cmd.args[i], 0o666, flags)) {
     41 		case let err: fs::error =>
     42 			fmt::fatalf("Error opening '{}' for writing: {}",
     43 				cmd.args[i], fs::strerror(err));
     44 		case let file: io::file =>
     45 			yield file;
     46 		};
     47 		source = &io::tee(source, file);
     48 		append(files, file);
     49 	};
     50 
     51 	io::copy(os::stdout, source)?;
     52 	return;
     53 };