From 947a3a1be92e0d5ddc5ad263d9434b31e8c170db Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Mon, 27 May 2024 15:55:32 -0700 Subject: [PATCH] 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(). --- lib/std/process/Child.zig | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/std/process/Child.zig b/lib/std/process/Child.zig index a31afdc66d..0599763c67 100644 --- a/lib/std/process/Child.zig +++ b/lib/std/process/Child.zig @@ -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); }