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 a31afdc66d5e68eed8f884e66231d792b52ce518..0599763c67e0f36a93b67a439a26e223c5e8fb45 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); } -- 2.54.0