summaryrefslogtreecommitdiff
path: root/io.c
diff options
context:
space:
mode:
authorakr <akr@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2011-10-29 11:59:46 +0000
committerakr <akr@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2011-10-29 11:59:46 +0000
commit54d7e82613237819c0a5c484d94c097ff068c259 (patch)
tree6492b2b6991736b8fd3d39569d9b7953717d7e4d /io.c
parenta9648d1e58260d35438d759dccf81cc45be9b45e (diff)
* io.c (rb_cloexec_dup): use F_DUPFD_CLOEXEC if available.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@33555 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'io.c')
-rw-r--r--io.c16
1 files changed, 16 insertions, 0 deletions
diff --git a/io.c b/io.c
index bde6ff4a36..fad64cafe8 100644
--- a/io.c
+++ b/io.c
@@ -205,7 +205,23 @@ int
rb_cloexec_dup(int oldfd)
{
int ret;
+
+#ifdef F_DUPFD_CLOEXEC
+ static int try_fcntl = 1;
+ if (try_fcntl) {
+ ret = fcntl(oldfd, F_DUPFD_CLOEXEC, 0);
+ /* F_DUPFD_CLOEXEC is available since Linux 2.6.24. Linux 2.6.18 fails with EINVAL */
+ if (ret == -1 && errno == EINVAL) {
+ try_fcntl = 0;
+ ret = dup(oldfd);
+ }
+ }
+ else {
+ ret = dup(oldfd);
+ }
+#else
ret = dup(oldfd);
+#endif
if (ret == -1) return -1;
fd_set_cloexec(ret);
return ret;