diff options
Diffstat (limited to 'src/unistd/dup3.c')
-rw-r--r-- | src/unistd/dup3.c | 26 |
1 files changed, 26 insertions, 0 deletions
diff --git a/src/unistd/dup3.c b/src/unistd/dup3.c new file mode 100644 index 0000000..40798bd --- /dev/null +++ b/src/unistd/dup3.c @@ -0,0 +1,26 @@ +#define _GNU_SOURCE +#include <unistd.h> +#include <errno.h> +#include <fcntl.h> +#include "syscall.h" + +int __dup3(int old, int new, int flags) +{ + int r; +#ifdef SYS_dup2 + if (old==new) return __syscall_ret(-EINVAL); + if (flags) { + while ((r=__syscall(SYS_dup3, old, new, flags))==-EBUSY); + if (r!=-ENOSYS) return __syscall_ret(r); + if (flags & ~O_CLOEXEC) return __syscall_ret(-EINVAL); + } + while ((r=__syscall(SYS_dup2, old, new))==-EBUSY); + 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 + return __syscall_ret(r); +} + +weak_alias(__dup3, dup3); |