I have a minimal program here https://codeberg.org/knightpp/ourio-repr/src/branch/main/src/main.zig.
The program uses ourio lib by @rockorager https://github.com/rockorager/ourio/ and designed to read from stdin and print number of bytes read. So then to use it I call echo test | zig build run
. But when it’s started by redirecting file like this zig build run < file.txt
→ read doesn’t return 0, so there’s no way to determine EOF?
const std = @import("std");
const io = @import("ourio");
const posix = std.posix;
pub fn main() !void {
var gpa = std.heap.DebugAllocator(.{}).init;
defer _ = gpa.deinit();
const allocator = gpa.allocator();
var rt = try io.Ring.init(allocator, 16);
defer rt.deinit();
const stdin_fd: posix.fd_t = posix.STDIN_FILENO;
const fd = stdin_fd;
const original_mode = try posix.fcntl(fd, posix.F.GETFL, 0);
var opts: posix.O = @bitCast(@as(u32, @intCast(original_mode)));
opts.NONBLOCK = true;
_ = try posix.fcntl(fd, posix.F.SETFL, @as(usize, @as(u32, @bitCast(opts))));
defer {
_ = posix.fcntl(fd, posix.F.SETFL, original_mode) catch |err| {
std.log.err("could not restore fd's mode: {}", .{err});
};
}
var app = Runner{ .in = fd };
try app.start(&rt);
try rt.run(.until_done);
}
const Runner = struct {
in: posix.fd_t,
buf: [4096]u8 = undefined,
fn start(self: *Runner, rt: *io.Ring) !void {
try self.read(rt);
}
fn read(self: *Runner, rt: *io.Ring) !void {
_ = try rt.read(self.in, &self.buf, .{
.ptr = self,
.msg = 0,
.cb = Runner.cb,
});
}
fn cb(rt: *io.Ring, task: io.Task) anyerror!void {
var self = task.userdataCast(Runner);
const result = task.result.?;
const n = try result.read;
if (n == 0) {
return;
}
std.debug.print("{d} bytes\n", .{n});
try self.read(rt);
}
};