aboutsummaryrefslogtreecommitdiffstats
path: root/io.c
diff options
context:
space:
mode:
Diffstat (limited to 'io.c')
-rw-r--r--io.c35
1 files changed, 21 insertions, 14 deletions
diff --git a/io.c b/io.c
index 04057b3b8b..9c96d8c944 100644
--- a/io.c
+++ b/io.c
@@ -239,25 +239,32 @@ rb_cloexec_dup2(int oldfd, int newfd)
{
int ret;
+ /* When oldfd == newfd, dup2 succeeds but dup3 fails with EINVAL.
+ * rb_cloexec_dup2 succeeds as dup2. */
+ if (oldfd == newfd) {
+ ret = newfd;
+ }
+ else {
#if defined(HAVE_DUP3) && defined(O_CLOEXEC)
- static int try_dup3 = 1;
- if (2 < newfd && try_dup3) {
- ret = dup3(oldfd, newfd, O_CLOEXEC);
- if (ret != -1)
- return ret;
- /* dup3 is available since Linux 2.6.27. */
- if (errno == ENOSYS) {
- try_dup3 = 0;
+ static int try_dup3 = 1;
+ if (2 < newfd && try_dup3) {
+ ret = dup3(oldfd, newfd, O_CLOEXEC);
+ if (ret != -1)
+ return ret;
+ /* dup3 is available since Linux 2.6.27. */
+ if (errno == ENOSYS) {
+ try_dup3 = 0;
+ ret = dup2(oldfd, newfd);
+ }
+ }
+ else {
ret = dup2(oldfd, newfd);
}
- }
- else {
- ret = dup2(oldfd, newfd);
- }
#else
- ret = dup2(oldfd, newfd);
+ ret = dup2(oldfd, newfd);
#endif
- if (ret == -1) return -1;
+ if (ret == -1) return -1;
+ }
fd_set_cloexec(ret);
return ret;
}