Index: lib/libc/gen/posix_spawn.c =================================================================== --- lib/libc/gen/posix_spawn.c +++ lib/libc/gen/posix_spawn.c @@ -161,15 +161,21 @@ return (EBADF); } } - if (_fcntl(fae->fae_fildes, F_SETFD, 0) == -1) - return (errno); break; case FAE_DUP2: - /* Perform a dup2() */ - if (_dup2(fae->fae_fildes, fae->fae_newfildes) == -1) - return (errno); - if (_fcntl(fae->fae_newfildes, F_SETFD, 0) == -1) + /* + * Perform a dup2(), except when we don't really need to. If + * old == new, dup2() will return successfully and leave the + * CLOEXEC flag untouched. Avoid it and just unconditionally + * clear the CLOEXEC flag. If we really do dup2(), the CLOEXEC + * flag is cleared already. + */ + if (fae->fae_fildes == fae->fae_newfildes) { + if (_fcntl(fae->fae_newfildes, F_SETFD, 0) == -1) + return (errno); + } else if (_dup2(fae->fae_fildes, fae->fae_newfildes) == -1) { return (errno); + } break; case FAE_CLOSE: /* Perform a close(), do not fail if already closed */ @@ -384,7 +390,7 @@ return (error); } fae->fae_fildes = fildes; - fae->fae_oflag = oflag; + fae->fae_oflag = oflag & ~O_CLOEXEC; fae->fae_mode = mode; STAILQ_INSERT_TAIL(&(*fa)->fa_list, fae, fae_list);