7367068b
feat(pty): add read/write helpers
a73x 2026-04-08 06:02
diff --git a/src/pty.zig b/src/pty.zig index 01e6e9b..2185a54 100644 --- a/src/pty.zig +++ b/src/pty.zig @@ -52,6 +52,14 @@ pub const Pty = struct { }; } pub fn read(self: *Pty, buf: []u8) !usize { return std.posix.read(self.master_fd, buf); } pub fn write(self: *Pty, data: []const u8) !usize { return std.posix.write(self.master_fd, data); } pub fn deinit(self: *Pty) void { std.posix.close(self.master_fd); _ = std.c.kill(self.child_pid, std.c.SIG.TERM); @@ -59,6 +67,41 @@ pub const Pty = struct { } }; test "Pty.write and read echoes through shell" { var pty = try Pty.spawn(.{ .cols = 80, .rows = 24, .shell = "/bin/sh", }); defer pty.deinit(); // Give shell a moment to start std.Thread.sleep(100 * std.time.ns_per_ms); // Write a command _ = try pty.write("echo hello\n"); // Drain output for up to 1 second var buf: [4096]u8 = undefined; var seen_hello = false; const deadline = std.time.nanoTimestamp() + 1 * std.time.ns_per_s; while (std.time.nanoTimestamp() < deadline) { const n = pty.read(&buf) catch |err| switch (err) { error.WouldBlock => { std.Thread.sleep(10 * std.time.ns_per_ms); continue; }, else => return err, }; if (n == 0) break; if (std.mem.indexOf(u8, buf[0..n], "hello") != null) { seen_hello = true; break; } } try std.testing.expect(seen_hello); } test "Pty.spawn launches /bin/sh and returns valid fd" { var pty = try Pty.spawn(.{ .cols = 80,