From 9e4cd1f4e6c3195665daa80c6a438cfd4daa92b1 Mon Sep 17 00:00:00 2001 From: Rabin Gaire Date: Wed, 20 Apr 2022 18:02:41 +0545 Subject: [PATCH] fix child process spawn on macos hangs issue When a child process with stdin, stdout behavior set to pipe is ran on macos it used to hang which has been fixed. Issue existed because we forgot to call `posix_spawn_file_actions_addclose` syscall on user exposed file descriptor which resulted on file descriptor not closing properly. --- lib/std/child_process.zig | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/lib/std/child_process.zig b/lib/std/child_process.zig index 8171ff7eea..aef96cbde3 100644 --- a/lib/std/child_process.zig +++ b/lib/std/child_process.zig @@ -593,9 +593,9 @@ pub const ChildProcess = struct { var actions = try os.posix_spawn.Actions.init(); defer actions.deinit(); - try setUpChildIoPosixSpawn(self.stdin_behavior, &actions, stdin_pipe[0], os.STDIN_FILENO, dev_null_fd); - try setUpChildIoPosixSpawn(self.stdout_behavior, &actions, stdout_pipe[1], os.STDOUT_FILENO, dev_null_fd); - try setUpChildIoPosixSpawn(self.stderr_behavior, &actions, stderr_pipe[1], os.STDERR_FILENO, dev_null_fd); + try setUpChildIoPosixSpawn(self.stdin_behavior, &actions, stdin_pipe, os.STDIN_FILENO, dev_null_fd); + try setUpChildIoPosixSpawn(self.stdout_behavior, &actions, stdout_pipe, os.STDOUT_FILENO, dev_null_fd); + try setUpChildIoPosixSpawn(self.stderr_behavior, &actions, stderr_pipe, os.STDERR_FILENO, dev_null_fd); if (self.cwd_dir) |cwd| { try actions.fchdir(cwd.fd); @@ -650,12 +650,16 @@ pub const ChildProcess = struct { fn setUpChildIoPosixSpawn( stdio: StdIo, actions: *os.posix_spawn.Actions, - pipe_fd: i32, + pipe_fd: [2]i32, std_fileno: i32, dev_null_fd: i32, ) !void { switch (stdio) { - .Pipe => try actions.dup2(pipe_fd, std_fileno), + .Pipe => { + const idx: usize = if (std_fileno == 0) 0 else 1; + try actions.dup2(pipe_fd[idx], std_fileno); + try actions.close(pipe_fd[1-idx]); + }, .Close => try actions.close(std_fileno), .Inherit => {}, .Ignore => try actions.dup2(dev_null_fd, std_fileno),