summaryrefslogtreecommitdiff
path: root/ext/socket/socket.c
diff options
context:
space:
mode:
authorakr <akr@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2011-11-05 02:19:48 +0000
committerakr <akr@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2011-11-05 02:19:48 +0000
commitdf390d82f9c53ba2a3404dc09997bc8a46d716f9 (patch)
tree597603cff6417c16a4d57c4e925fda69e9c6327f /ext/socket/socket.c
parent413f24d3b01ee6ceaf8b025cf64e05155689fdbe (diff)
* ext/socket/socket.c (rsock_socketpair0): don't clear
try_sock_cloexec if SOCK_CLOEXEC is not a reason for EINVAL. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@33635 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'ext/socket/socket.c')
-rw-r--r--ext/socket/socket.c40
1 files changed, 22 insertions, 18 deletions
diff --git a/ext/socket/socket.c b/ext/socket/socket.c
index 0752793d88..402675c5b0 100644
--- a/ext/socket/socket.c
+++ b/ext/socket/socket.c
@@ -78,32 +78,36 @@ pair_yield(VALUE pair)
#if defined HAVE_SOCKETPAIR
static int
-rsock_socketpair0(int domain, int type0, int protocol, int sv[2])
+rsock_socketpair0(int domain, int type, int protocol, int sv[2])
{
- int ret, type;
+ int ret;
#ifdef SOCK_CLOEXEC
static int try_sock_cloexec = 1;
- if (try_sock_cloexec)
- type = type0|SOCK_CLOEXEC;
- else
- type = type0;
- retry_without_sock_cloexec:;
+ if (try_sock_cloexec) {
+ ret = socketpair(domain, type|SOCK_CLOEXEC, protocol, sv);
+ if (ret == -1) {
+ /* SOCK_CLOEXEC is available since Linux 2.6.27. Linux 2.6.18 fails with EINVAL */
+ if (try_sock_cloexec && errno == EINVAL) {
+ ret = socketpair(domain, type, protocol, sv);
+ if (ret != -1) {
+ /* The reason of EINVAL may be other than SOCK_CLOEXEC.
+ * So disable SOCK_CLOEXEC only if socketpair() succeeds without SOCK_CLOEXEC.
+ * Ex. Socket.pair(:UNIX, 0xff) fails with EINVAL.
+ */
+ try_sock_cloexec = 0;
+ }
+ }
+ }
+ }
+ else {
+ ret = socketpair(domain, type, protocol, sv);
+ }
#else
- type = type0;
-#endif
-
ret = socketpair(domain, type, protocol, sv);
+#endif
if (ret == -1) {
-#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
return -1;
}