Skip to content

Commit b878ce2

Browse files
committed
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().
1 parent c9c5210 commit b878ce2

File tree

1 file changed

+4
-1
lines changed

1 file changed

+4
-1
lines changed

lib/std/process/Child.zig

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -654,14 +654,17 @@ fn spawnPosix(self: *ChildProcess) SpawnError!void {
654654
setUpChildIo(self.stdin_behavior, stdin_pipe[0], posix.STDIN_FILENO, dev_null_fd) catch |err| forkChildErrReport(err_pipe[1], err);
655655
setUpChildIo(self.stdout_behavior, stdout_pipe[1], posix.STDOUT_FILENO, dev_null_fd) catch |err| forkChildErrReport(err_pipe[1], err);
656656
setUpChildIo(self.stderr_behavior, stderr_pipe[1], posix.STDERR_FILENO, dev_null_fd) catch |err| forkChildErrReport(err_pipe[1], err);
657-
if (prog_pipe[1] != -1) posix.dup2(prog_pipe[1], prog_fileno) catch |err| forkChildErrReport(err_pipe[1], err);
658657

659658
if (self.cwd_dir) |cwd| {
660659
posix.fchdir(cwd.fd) catch |err| forkChildErrReport(err_pipe[1], err);
661660
} else if (self.cwd) |cwd| {
662661
posix.chdir(cwd) catch |err| forkChildErrReport(err_pipe[1], err);
663662
}
664663

664+
// Must happen after fchdir above, the cwd file descriptor might be
665+
// equal to prog_fileno and be clobbered by this dup2 call.
666+
if (prog_pipe[1] != -1) posix.dup2(prog_pipe[1], prog_fileno) catch |err| forkChildErrReport(err_pipe[1], err);
667+
665668
if (self.gid) |gid| {
666669
posix.setregid(gid, gid) catch |err| forkChildErrReport(err_pipe[1], err);
667670
}

0 commit comments

Comments
 (0)