7367068b
feat(pty): add read/write helpers
a73x 2026-04-08 06:02
Commit message
src/pty.zig
| Old | New | ||
|---|---|---|---|
| @@ -52,6 +52,14 @@ pub const Pty = struct { | |||
| 52 | }; | 52 | }; |
| 53 | } | 53 | } |
| 54 | 54 | ||
| 55 | pub fn read(self: *Pty, buf: []u8) !usize { | ||
| 56 | return std.posix.read(self.master_fd, buf); | ||
| 57 | } | ||
| 58 | |||
| 59 | pub fn write(self: *Pty, data: []const u8) !usize { | ||
| 60 | return std.posix.write(self.master_fd, data); | ||
| 61 | } | ||
| 62 | |||
| 55 | pub fn deinit(self: *Pty) void { | 63 | pub fn deinit(self: *Pty) void { |
| 56 | std.posix.close(self.master_fd); | 64 | std.posix.close(self.master_fd); |
| 57 | _ = std.c.kill(self.child_pid, std.c.SIG.TERM); | 65 | _ = std.c.kill(self.child_pid, std.c.SIG.TERM); |
| @@ -59,6 +67,41 @@ pub const Pty = struct { | |||
| 59 | } | 67 | } |
| 60 | }; | 68 | }; |
| 61 | 69 | ||
| 70 | test "Pty.write and read echoes through shell" { | ||
| 71 | var pty = try Pty.spawn(.{ | ||
| 72 | .cols = 80, | ||
| 73 | .rows = 24, | ||
| 74 | .shell = "/bin/sh", | ||
| 75 | }); | ||
| 76 | defer pty.deinit(); | ||
| 77 | |||
| 78 | // Give shell a moment to start | ||
| 79 | std.Thread.sleep(100 * std.time.ns_per_ms); | ||
| 80 | |||
| 81 | // Write a command | ||
| 82 | _ = try pty.write("echo hello\n"); | ||
| 83 | |||
| 84 | // Drain output for up to 1 second | ||
| 85 | var buf: [4096]u8 = undefined; | ||
| 86 | var seen_hello = false; | ||
| 87 | const deadline = std.time.nanoTimestamp() + 1 * std.time.ns_per_s; | ||
| 88 | while (std.time.nanoTimestamp() < deadline) { | ||
| 89 | const n = pty.read(&buf) catch |err| switch (err) { | ||
| 90 | error.WouldBlock => { | ||
| 91 | std.Thread.sleep(10 * std.time.ns_per_ms); | ||
| 92 | continue; | ||
| 93 | }, | ||
| 94 | else => return err, | ||
| 95 | }; | ||
| 96 | if (n == 0) break; | ||
| 97 | if (std.mem.indexOf(u8, buf[0..n], "hello") != null) { | ||
| 98 | seen_hello = true; | ||
| 99 | break; | ||
| 100 | } | ||
| 101 | } | ||
| 102 | try std.testing.expect(seen_hello); | ||
| 103 | } | ||
| 104 | |||
| 62 | test "Pty.spawn launches /bin/sh and returns valid fd" { | 105 | test "Pty.spawn launches /bin/sh and returns valid fd" { |
| 63 | var pty = try Pty.spawn(.{ | 106 | var pty = try Pty.spawn(.{ |
| 64 | .cols = 80, | 107 | .cols = 80, |