mirror of
https://github.com/ziglang/zig.git
synced 2026-02-11 03:51:08 +00:00
Thanks to the Windows Process Environment Block, it is possible to obtain handles to the standard input, output, and error streams without possibility of failure.
69 lines
1.8 KiB
Zig
69 lines
1.8 KiB
Zig
const std = @import("std");
|
|
const io = std.io;
|
|
const process = std.process;
|
|
const File = std.fs.File;
|
|
const mem = std.mem;
|
|
const warn = std.debug.warn;
|
|
const allocator = std.debug.global_allocator;
|
|
|
|
pub fn main() !void {
|
|
var args_it = process.args();
|
|
const exe = try unwrapArg(args_it.next(allocator).?);
|
|
var catted_anything = false;
|
|
const stdout_file = io.getStdOut();
|
|
|
|
while (args_it.next(allocator)) |arg_or_err| {
|
|
const arg = try unwrapArg(arg_or_err);
|
|
if (mem.eql(u8, arg, "-")) {
|
|
catted_anything = true;
|
|
try cat_file(stdout_file, io.getStdIn());
|
|
} else if (arg[0] == '-') {
|
|
return usage(exe);
|
|
} else {
|
|
const file = File.openRead(arg) catch |err| {
|
|
warn("Unable to open file: {}\n", @errorName(err));
|
|
return err;
|
|
};
|
|
defer file.close();
|
|
|
|
catted_anything = true;
|
|
try cat_file(stdout_file, file);
|
|
}
|
|
}
|
|
if (!catted_anything) {
|
|
try cat_file(stdout_file, io.getStdIn());
|
|
}
|
|
}
|
|
|
|
fn usage(exe: []const u8) !void {
|
|
warn("Usage: {} [FILE]...\n", exe);
|
|
return error.Invalid;
|
|
}
|
|
|
|
fn cat_file(stdout: File, file: File) !void {
|
|
var buf: [1024 * 4]u8 = undefined;
|
|
|
|
while (true) {
|
|
const bytes_read = file.read(buf[0..]) catch |err| {
|
|
warn("Unable to read from stream: {}\n", @errorName(err));
|
|
return err;
|
|
};
|
|
|
|
if (bytes_read == 0) {
|
|
break;
|
|
}
|
|
|
|
stdout.write(buf[0..bytes_read]) catch |err| {
|
|
warn("Unable to write to stdout: {}\n", @errorName(err));
|
|
return err;
|
|
};
|
|
}
|
|
}
|
|
|
|
fn unwrapArg(arg: anyerror![]u8) ![]u8 {
|
|
return arg catch |err| {
|
|
warn("Unable to parse command line: {}\n", err);
|
|
return err;
|
|
};
|
|
}
|