SIGN IN SIGN UP

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