diff --git a/build.zig.zon b/build.zig.zon index 5ea83cc..09d3c13 100644 --- a/build.zig.zon +++ b/build.zig.zon @@ -30,8 +30,8 @@ .hash = "fuzzig-0.1.1-Ji0xivxIAQBD0g8O_NV_0foqoPf3elsg9Sc3pNfdVH4D", }, .vaxis = .{ - .url = "git+https://github.com/neurocyte/libvaxis?ref=main#03fe1b123afdaf879829da507f54e42780d4ec65", - .hash = "vaxis-0.5.1-BWNV_EJOCQCOD5tzfVqOgDUSYfvBLrokxE0fr9MSb05q", + .url = "git+https://github.com/neurocyte/libvaxis?ref=main#8fba2b2b14174f73a957b3b4b0e1c30f25a78577", + .hash = "vaxis-0.5.1-BWNV_HJQCQAVq-jmKeSh0Ur4DLbkc3DUP-amXI3k22TB", }, .zeit = .{ .url = "git+https://github.com/rockorager/zeit?ref=zig-0.15#ed2ca60db118414bda2b12df2039e33bad3b0b88", diff --git a/src/tui/terminal_view.zig b/src/tui/terminal_view.zig index d9d123b..bbc2746 100644 --- a/src/tui/terminal_view.zig +++ b/src/tui/terminal_view.zig @@ -271,7 +271,7 @@ const Vt = struct { self.cwd.deinit(allocator); self.title.deinit(allocator); if (self.pty_pid) |pid| { - pid.send(.{ "pty_actor", "quit" }) catch {}; + pid.send(.{"quit"}) catch {}; pid.deinit(); self.pty_pid = null; } @@ -340,16 +340,20 @@ const pty = struct { errdefer self.deinit(); if (try m.match(.{ "fd", "pty", "read_ready" })) { - try self.read_and_process(); - return; - } - - if (try m.match(.{ "pty_actor", "quit" })) { + self.read_and_process() catch |e| return switch (e) { + error.Terminated => tp.exit_normal(), + error.InputOutput => tp.exit_normal(), + error.SendFailed => tp.exit_normal(), + error.Unexpected => tp.exit_normal(), + }; + } else if (try m.match(.{"quit"})) { return tp.exit_normal(); + } else { + return tp.unexpected(m); } } - fn read_and_process(self: *@This()) tp.result { + fn read_and_process(self: *@This()) error{ Terminated, InputOutput, SendFailed, Unexpected }!void { var buf: [4096]u8 = undefined; while (true) { @@ -359,27 +363,57 @@ const pty = struct { const code = self.vt.cmd.wait(); self.vt.event_queue.push(.{ .exited = code }); self.parent.send(.{ "terminal_view", "output" }) catch {}; - return tp.exit_normal(); + return error.InputOutput; + }, + error.SystemResources, + error.IsDir, + error.OperationAborted, + error.BrokenPipe, + error.ConnectionResetByPeer, + error.ConnectionTimedOut, + error.NotOpenForReading, + error.SocketNotConnected, + error.Canceled, + error.AccessDenied, + error.ProcessNotFound, + error.LockViolation, + error.Unexpected, + => { + std.log.err("terminal_view: read unexpected: {}", .{e}); + return error.Unexpected; }, - else => return tp.exit_error(e, @errorReturnTrace()), }; if (n == 0) { const code = self.vt.cmd.wait(); self.vt.event_queue.push(.{ .exited = code }); self.parent.send(.{ "terminal_view", "output" }) catch {}; - return tp.exit_normal(); + return error.Terminated; } - const exited = self.vt.processOutput(&self.parser, buf[0..n]) catch |e| - return tp.exit_error(e, @errorReturnTrace()); - if (exited) { - self.parent.send(.{ "terminal_view", "output" }) catch {}; - return tp.exit_normal(); + defer self.parent.send(.{ "terminal_view", "output" }) catch {}; + + switch (self.vt.processOutput(&self.parser, buf[0..n]) catch |e| switch (e) { + error.WriteFailed, + error.ReadFailed, + error.OutOfMemory, + error.Utf8InvalidStartByte, + => { + std.log.err("terminal_view: processOutput unexpected: {}", .{e}); + return error.Unexpected; + }, + }) { + .exited => { + return error.Terminated; + }, + .running => {}, } - // Notify parent that new output is available. - self.parent.send(.{ "terminal_view", "output" }) catch {}; } - self.fd.wait_read() catch |e| return tp.exit_error(e, @errorReturnTrace()); + self.fd.wait_read() catch |e| switch (e) { + error.ThespianFileDescriptorWaitReadFailed => { + std.log.err("terminal_view: wait_read unexpected: {}", .{e}); + return error.Unexpected; + }, + }; } };