From 6ef757a8f85db7a124d370378850339a899c9e65 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Thu, 9 Jan 2025 12:43:41 -0800 Subject: [PATCH] Revert "termio/exec: fix SIGPIPE crash when reader exits early" This reverts commit 3e24e96af51fe308705a1f1695e3b9045c54482e. --- src/termio/Exec.zig | 25 +++++++++---------------- 1 file changed, 9 insertions(+), 16 deletions(-) diff --git a/src/termio/Exec.zig b/src/termio/Exec.zig index d409ccbb0..1a3b8cad0 100644 --- a/src/termio/Exec.zig +++ b/src/termio/Exec.zig @@ -179,11 +179,8 @@ pub fn threadExit(self: *Exec, td: *termio.Termio.ThreadData) void { // Quit our read thread after exiting the subprocess so that // we don't get stuck waiting for data to stop flowing if it is // a particularly noisy process. - if (exec.read_thread_pipe) |pipe| { - posix.close(pipe); - // Tell deinit that we've already closed the pipe - exec.read_thread_pipe = null; - } + _ = posix.write(exec.read_thread_pipe, "x") catch |err| + log.warn("error writing to read thread quit pipe err={}", .{err}); if (comptime builtin.os.tag == .windows) { // Interrupt the blocking read so the thread can see the quit message @@ -642,7 +639,7 @@ pub const ThreadData = struct { /// Reader thread state read_thread: std.Thread, - read_thread_pipe: ?posix.fd_t, + read_thread_pipe: posix.fd_t, read_thread_fd: posix.fd_t, /// The timer to detect termios state changes. @@ -655,8 +652,7 @@ pub const ThreadData = struct { termios_mode: ptypkg.Mode = .{}, pub fn deinit(self: *ThreadData, alloc: Allocator) void { - // If the pipe isn't closed, close it. - if (self.read_thread_pipe) |pipe| posix.close(pipe); + posix.close(self.read_thread_pipe); // Clear our write pools. We know we aren't ever going to do // any more IO since we stop our data stream below so we can just @@ -1437,12 +1433,9 @@ pub const ReadThread = struct { }; // This happens on macOS instead of WouldBlock when the - // child process dies. It's equivalent to NotOpenForReading - // so we can just exit. - if (n == 0) { - log.info("io reader exiting", .{}); - return; - } + // child process dies. To be safe, we just break the loop + // and let our poll happen. + if (n == 0) break; // log.info("DATA: {d}", .{n}); @call(.always_inline, termio.Termio.processOutput, .{ io, buf[0..n] }); @@ -1454,8 +1447,8 @@ pub const ReadThread = struct { return; }; - // If our quit fd is closed, we're done. - if (pollfds[1].revents & posix.POLL.HUP != 0) { + // If our quit fd is set, we're done. + if (pollfds[1].revents & posix.POLL.IN != 0) { log.info("read thread got quit signal", .{}); return; }