From da5ae5544d4abd95b94df303018684847e1d88f8 Mon Sep 17 00:00:00 2001 From: akr Date: Mon, 31 Oct 2011 03:07:26 +0000 Subject: [PATCH] * io.c (rb_cloexec_dup2): check oldfd == newfd at first. pointed by KOSAKI Motohiro. [ruby-dev:44713] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@33579 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 5 +++++ io.c | 37 ++++++++++++++++++++++--------------- 2 files changed, 27 insertions(+), 15 deletions(-) diff --git a/ChangeLog b/ChangeLog index 0ea58d809e..11ddbd2da8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +Mon Oct 31 12:05:24 2011 Tanaka Akira + + * io.c (rb_cloexec_dup2): check oldfd == newfd at first. + pointed by KOSAKI Motohiro. [ruby-dev:44713] + Mon Oct 31 10:50:26 2011 NAKAMURA Usaku * io.c (rb_cloexec_fcntl_dupfd): this function needs F_DUPFD. 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; -#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; - ret = dup2(oldfd, newfd); - } + /* When oldfd == newfd, dup2 succeeds but dup3 fails with EINVAL. + * rb_cloexec_dup2 succeeds as dup2. */ + if (oldfd == newfd) { + ret = newfd; } else { - ret = dup2(oldfd, newfd); - } +#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; + 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; }