summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog5
-rw-r--r--ext/socket/socket.c40
2 files changed, 27 insertions, 18 deletions
diff --git a/ChangeLog b/ChangeLog
index ae3bd1d1f2..273b447284 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+Sat Nov 5 11:18:12 2011 Tanaka Akira <akr@fsij.org>
+
+ * ext/socket/socket.c (rsock_socketpair0): don't clear
+ try_sock_cloexec if SOCK_CLOEXEC is not a reason for EINVAL.
+
Fri Nov 4 14:08:19 2011 Hiroshi Nakamura <nahi@ruby-lang.org>
* ext/openssl/ossl_pkey_rsa.c (rsa_generate): [SECURITY] Set RSA
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;
}