From f5e10c4a391c7f9c5347858bda1b173a56b393a7 Mon Sep 17 00:00:00 2001 From: Ben Gamari Date: Tue, 14 Jun 2022 09:37:36 -0400 Subject: [PATCH] cbits/fork-exec: Don't dup2 identical fds Darwin violates POSIX by making `dup2(x,x)`, which should be a no-op, error. Consequently, we must take care not to `dup2` in such cases. We had already made this change in the `posix_spawnp` codepath but I had assumed that this *only* affected `posix_spawnp`, not the `dup2` system call itself. --- cbits/posix/fork_exec.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/cbits/posix/fork_exec.c b/cbits/posix/fork_exec.c index ef8e581f..e7b6398d 100644 --- a/cbits/posix/fork_exec.c +++ b/cbits/posix/fork_exec.c @@ -69,8 +69,13 @@ setup_std_handle_fork(int fd, return 0; case STD_HANDLE_USE_FD: - if (dup2(b->use_fd, fd) == -1) { - child_failed(pipe, "dup2"); + // N.B. POSIX specifies that dup2(x,x) should be a no-op, but + // naturally Apple ignores this and rather fails in posix_spawn on Big + // Sur. + if (b->use_fd != fd) { + if (dup2(b->use_fd, fd) == -1) { + child_failed(pipe, "dup2"); + } } return 0;