Keep pipe ends off the standard descriptors (#118)
#115 creates the stdio pipes close-on-exec, and subprocess_create_ex then installs them on 0, 1 and 2. Duplicating a descriptor onto itself is a no-op, so an end that already landed on a standard descriptor keeps FD_CLOEXEC and exec closes the child's stream. It happens whenever the parent runs with one of those descriptors free. posix_spawn_file_actions_adddup2 is documented on macOS as behaving "as if dup2() had been called", with no special case for equal descriptors, and that is where it bites. glibc applies the POSIX clarification and clears the flag, which is why no Linux runner shows this. subprocess_fds_above_std moves such an end out of the way at creation time. That removes the self-duplication for every caller rather than patching each site, and it needs no platform test. The added test checks the precondition rather than the symptom: no pipe end may sit on 0, 1 or 2. That is observable everywhere, and it goes red on unpatched main — the symptom itself cannot be reproduced off macOS. Measured: full suite green on x86_64 glibc, and green on macOS in a run that combined this with the AIX branch and the pending utest.h changes, where the same suite had been failing on exactly this before.
B
Bernard Ladenthin committed
6f54d856c6ca324b150ea0a117bf1db64806a4d8
Parent: 0d76f78
Committed by GitHub <noreply@github.com>
on 8/18/2026, 7:40:36 PM