From 48362a307c85625020bf753efbf007395eb058a0 Mon Sep 17 00:00:00 2001 From: Tim Culverhouse Date: Wed, 17 Jan 2024 22:34:40 -0600 Subject: [PATCH] tty: use simple os.read loop instead of xev Signed-off-by: Tim Culverhouse --- src/main.zig | 9 ++++++- src/tty/Tty.zig | 69 ++++++++++++------------------------------------- 2 files changed, 24 insertions(+), 54 deletions(-) diff --git a/src/main.zig b/src/main.zig index 19924bd..1784f98 100644 --- a/src/main.zig +++ b/src/main.zig @@ -15,7 +15,14 @@ pub fn main() !void { var tty = try Tty.init(); defer tty.deinit(); - try tty.run(); + const pipe = try std.os.pipe(); + // run our tty read loop in it's own thread + const read_thread = try std.Thread.spawn(.{}, Tty.run, .{ &tty, pipe[0] }); + try read_thread.setName("tty"); + + std.time.sleep(100_000_000_0); + _ = try std.os.write(pipe[1], "q"); + read_thread.join(); try stdout.print("Run `zig build test` to run the tests.\n", .{}); diff --git a/src/tty/Tty.zig b/src/tty/Tty.zig index 1272d00..6eab9da 100644 --- a/src/tty/Tty.zig +++ b/src/tty/Tty.zig @@ -12,33 +12,17 @@ termios: os.termios, /// The file descriptor we are using for I/O fd: os.fd_t, -/// Stream attached to our fd -stream: xev.Stream, - -/// event loop -loop: xev.Loop, - -read_buffer: [1024]u8 = undefined, - /// initializes a Tty instance by opening /dev/tty and "making it raw" pub fn init() !Tty { // Open our tty const fd = try os.open("/dev/tty", os.system.O.RDWR, 0); - // Initialize the stream - const stream = xev.Stream.initFd(fd); - - // Initialize event loop - const loop = try xev.Loop.init(.{}); - // Set the termios of the tty const termios = try makeRaw(fd); return Tty{ .fd = fd, - .stream = stream, .termios = termios, - .loop = loop, }; } @@ -48,47 +32,26 @@ pub fn deinit(self: *Tty) void { log.err("couldn't restore terminal: {}", .{err}); }; os.close(self.fd); - self.stream.deinit(); - self.loop.deinit(); } /// read input from the tty -pub fn run(self: *Tty) !void { - var c_stream: xev.Completion = undefined; - - // Initialize our read event - self.stream.read( - &self.loop, - &c_stream, - .{ .slice = self.read_buffer[0..] }, - Tty, - self, - readCallback, - ); - - try self.loop.run(.until_done); -} - -fn readCallback( - ud: ?*Tty, - loop: *xev.Loop, - c: *xev.Completion, - stream: xev.Stream, - buf: xev.ReadBuffer, - r: xev.ReadError!usize, -) xev.CallbackAction { - _ = stream; // autofix - _ = c; // autofix - _ = loop; // autofix - const tty = ud.?; - _ = tty; // autofix - const n = r catch |err| { - // Log the error and shutdown - log.err("read error: {}", .{err}); - return .disarm; +pub fn run(self: *Tty, quit: os.fd_t) !void { + defer os.close(quit); + var buf: [1024]u8 = undefined; + var pollfds: [2]std.os.pollfd = .{ + .{ .fd = self.fd, .events = std.os.POLL.IN, .revents = undefined }, + .{ .fd = quit, .events = std.os.POLL.IN, .revents = undefined }, }; - log.info("{s}\r", .{buf.slice[0..n]}); - return .rearm; + while (true) { + _ = try std.os.poll(&pollfds, -1); + if (pollfds[1].revents & std.os.POLL.IN != 0) { + log.info("read thread got quit signal", .{}); + return; + } + + const n = try os.read(self.fd, &buf); + log.err("{s}", .{buf[0..n]}); + } } /// makeRaw enters the raw state for the terminal.