std.process.Child: fix spawning child proc with new cwd fd

Before this fix, the dup2 of the progress pipe was clobbering the cwd
fd, causing the fchdir to return ENOTDIR in between fork() and exec().
This commit is contained in:
Andrew Kelley 2024-05-27 15:55:32 -07:00
parent b7889f262a
commit 947a3a1be9

View file

@ -654,7 +654,6 @@ fn spawnPosix(self: *ChildProcess) SpawnError!void {
setUpChildIo(self.stdin_behavior, stdin_pipe[0], posix.STDIN_FILENO, dev_null_fd) catch |err| forkChildErrReport(err_pipe[1], err);
setUpChildIo(self.stdout_behavior, stdout_pipe[1], posix.STDOUT_FILENO, dev_null_fd) catch |err| forkChildErrReport(err_pipe[1], err);
setUpChildIo(self.stderr_behavior, stderr_pipe[1], posix.STDERR_FILENO, dev_null_fd) catch |err| forkChildErrReport(err_pipe[1], err);
if (prog_pipe[1] != -1) posix.dup2(prog_pipe[1], prog_fileno) catch |err| forkChildErrReport(err_pipe[1], err);
if (self.cwd_dir) |cwd| {
posix.fchdir(cwd.fd) catch |err| forkChildErrReport(err_pipe[1], err);
@ -662,6 +661,10 @@ fn spawnPosix(self: *ChildProcess) SpawnError!void {
posix.chdir(cwd) catch |err| forkChildErrReport(err_pipe[1], err);
}
// Must happen after fchdir above, the cwd file descriptor might be
// equal to prog_fileno and be clobbered by this dup2 call.
if (prog_pipe[1] != -1) posix.dup2(prog_pipe[1], prog_fileno) catch |err| forkChildErrReport(err_pipe[1], err);
if (self.gid) |gid| {
posix.setregid(gid, gid) catch |err| forkChildErrReport(err_pipe[1], err);
}