diff --git a/ChangeLog b/ChangeLog index cd2ccdbf7e..c1cf0c714c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +Sat Oct 29 20:59:08 2011 Tanaka Akira + + * io.c (rb_cloexec_dup): use F_DUPFD_CLOEXEC if available. + Sat Oct 29 20:00:26 2011 Tanaka Akira * include/ruby/intern.h (rb_cloexec_dup): declared. 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;