Skip to content

Commit 6ef757a

Browse files
committed
Revert "termio/exec: fix SIGPIPE crash when reader exits early"
This reverts commit 3e24e96.
1 parent 12ce9f2 commit 6ef757a

File tree

1 file changed

+9
-16
lines changed

1 file changed

+9
-16
lines changed

src/termio/Exec.zig

+9-16
Original file line numberDiff line numberDiff line change
@@ -179,11 +179,8 @@ pub fn threadExit(self: *Exec, td: *termio.Termio.ThreadData) void {
179179
// Quit our read thread after exiting the subprocess so that
180180
// we don't get stuck waiting for data to stop flowing if it is
181181
// a particularly noisy process.
182-
if (exec.read_thread_pipe) |pipe| {
183-
posix.close(pipe);
184-
// Tell deinit that we've already closed the pipe
185-
exec.read_thread_pipe = null;
186-
}
182+
_ = posix.write(exec.read_thread_pipe, "x") catch |err|
183+
log.warn("error writing to read thread quit pipe err={}", .{err});
187184

188185
if (comptime builtin.os.tag == .windows) {
189186
// Interrupt the blocking read so the thread can see the quit message
@@ -642,7 +639,7 @@ pub const ThreadData = struct {
642639

643640
/// Reader thread state
644641
read_thread: std.Thread,
645-
read_thread_pipe: ?posix.fd_t,
642+
read_thread_pipe: posix.fd_t,
646643
read_thread_fd: posix.fd_t,
647644

648645
/// The timer to detect termios state changes.
@@ -655,8 +652,7 @@ pub const ThreadData = struct {
655652
termios_mode: ptypkg.Mode = .{},
656653

657654
pub fn deinit(self: *ThreadData, alloc: Allocator) void {
658-
// If the pipe isn't closed, close it.
659-
if (self.read_thread_pipe) |pipe| posix.close(pipe);
655+
posix.close(self.read_thread_pipe);
660656

661657
// Clear our write pools. We know we aren't ever going to do
662658
// any more IO since we stop our data stream below so we can just
@@ -1437,12 +1433,9 @@ pub const ReadThread = struct {
14371433
};
14381434

14391435
// This happens on macOS instead of WouldBlock when the
1440-
// child process dies. It's equivalent to NotOpenForReading
1441-
// so we can just exit.
1442-
if (n == 0) {
1443-
log.info("io reader exiting", .{});
1444-
return;
1445-
}
1436+
// child process dies. To be safe, we just break the loop
1437+
// and let our poll happen.
1438+
if (n == 0) break;
14461439

14471440
// log.info("DATA: {d}", .{n});
14481441
@call(.always_inline, termio.Termio.processOutput, .{ io, buf[0..n] });
@@ -1454,8 +1447,8 @@ pub const ReadThread = struct {
14541447
return;
14551448
};
14561449

1457-
// If our quit fd is closed, we're done.
1458-
if (pollfds[1].revents & posix.POLL.HUP != 0) {
1450+
// If our quit fd is set, we're done.
1451+
if (pollfds[1].revents & posix.POLL.IN != 0) {
14591452
log.info("read thread got quit signal", .{});
14601453
return;
14611454
}

0 commit comments

Comments
 (0)