From ee5ae134dd1c0037a36b2e0c78cd4e326d002c3a Mon Sep 17 00:00:00 2001 From: akr Date: Mon, 31 Oct 2011 21:01:18 +0000 Subject: [PATCH] * ext/socket/socket.c (rsock_socketpair): use SOCK_CLOEXEC if available. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@33593 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 5 +++++ ext/socket/socket.c | 31 ++++++++++++++++++++++++++----- 2 files changed, 31 insertions(+), 5 deletions(-) diff --git a/ChangeLog b/ChangeLog index b6828bbc84..80fae2c9ff 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +Tue Nov 1 05:59:41 2011 Tanaka Akira + + * ext/socket/socket.c (rsock_socketpair): use SOCK_CLOEXEC if + available. + Tue Nov 1 02:56:17 2011 NAKAMURA Usaku * ruby.c (load_file_internal): convert the encoding of load path if diff --git a/ext/socket/socket.c b/ext/socket/socket.c index 31346a0295..aa1749bb4a 100644 --- a/ext/socket/socket.c +++ b/ext/socket/socket.c @@ -78,14 +78,35 @@ pair_yield(VALUE pair) #if defined HAVE_SOCKETPAIR static int -rsock_socketpair(int domain, int type, int protocol, int sv[2]) +rsock_socketpair(int domain, int type0, int protocol, int sv[2]) { - int ret; + int ret, type; + +#ifdef SOCK_CLOEXEC + static int try_sock_cloexec = 1; + if (try_sock_cloexec) + type = type0|SOCK_CLOEXEC; + else + type = type0; + retry_without_sock_cloexec:; +#else + type = type0; +#endif ret = socketpair(domain, type, protocol, sv); - if (ret < 0 && (errno == EMFILE || errno == ENFILE)) { - rb_gc(); - ret = socketpair(domain, type, protocol, sv); + if (ret < 0) { +#ifdef SOCK_CLOEXEC + /* SOCK_CLOEXEC is available since Linux 2.6.27. Linux 2.6.18 fails with EINVAL */ + if (try_sock_cloexec && errno == EINVAL) { + try_sock_cloexec = 0; + type = type0; + goto retry_without_sock_cloexec; + } +#endif + if (errno == EMFILE || errno == ENFILE) { + rb_gc(); + ret = socketpair(domain, type, protocol, sv); + } } return ret;