aboutsummaryrefslogtreecommitdiff
path: root/src/unistd
diff options
context:
space:
mode:
authorRich Felker <dalias@aerifal.cx>2023-02-28 15:44:46 -0500
committerRich Felker <dalias@aerifal.cx>2023-02-28 15:44:46 -0500
commit3281047cfca0f3848d0613e3c0d19d41b0531564 (patch)
tree92a91bd746e35c5bc9a7f59db9d1d73c89fa50af /src/unistd
parentc99b7daafdbf1e2415bf408e67ca7813e7ddeedf (diff)
downloadmusl-3281047cfca0f3848d0613e3c0d19d41b0531564.zip
musl-3281047cfca0f3848d0613e3c0d19d41b0531564.tar.gz
musl-3281047cfca0f3848d0613e3c0d19d41b0531564.tar.bz2
dup3: don't set FD_CLOEXEC on failure on kernels without dup3 syscall
this is the best-effort fallback path for kernels that can't actually support the dup3 functionality. it was setting FD_CLOEXEC flag on the target fd (new) even if the dup2 operation failed. normally that shouldn't happen under correct usage, but it's possible if the source fd is not open or intentionally invalid (e.g. -1).
Diffstat (limited to 'src/unistd')
-rw-r--r--src/unistd/dup3.c3
1 files changed, 2 insertions, 1 deletions
diff --git a/src/unistd/dup3.c b/src/unistd/dup3.c
index 1e7dc3e..40798bd 100644
--- a/src/unistd/dup3.c
+++ b/src/unistd/dup3.c
@@ -15,7 +15,8 @@ int __dup3(int old, int new, int flags)
if (flags & ~O_CLOEXEC) return __syscall_ret(-EINVAL);
}
while ((r=__syscall(SYS_dup2, old, new))==-EBUSY);
- if (flags & O_CLOEXEC) __syscall(SYS_fcntl, new, F_SETFD, FD_CLOEXEC);
+ if (r >= 0 && (flags & O_CLOEXEC))
+ __syscall(SYS_fcntl, new, F_SETFD, FD_CLOEXEC);
#else
while ((r=__syscall(SYS_dup3, old, new, flags))==-EBUSY);
#endif