summaryrefslogtreecommitdiff
path: root/ext/socket/init.c
diff options
context:
space:
mode:
authornormal <normal@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2018-11-08 03:27:16 +0000
committernormal <normal@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2018-11-08 03:27:16 +0000
commit86dca76ef2faaa13706e99ac6b6f49d57348df86 (patch)
tree1776a29c858c38e7a13c49f781c4842d56778108 /ext/socket/init.c
parent17e9667fe9707ff5f20cc320cbd111f886caa5b9 (diff)
ext/socket/init.c (wait_connectable): bail out early on some errors
This becomes necesary if sockets become non-blocking by default <https://bugs.ruby-lang.org/issues/14968>; but it's always been possible to make sockets non-blocking anyways. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65619 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'ext/socket/init.c')
-rw-r--r--ext/socket/init.c21
1 files changed, 20 insertions, 1 deletions
diff --git a/ext/socket/init.c b/ext/socket/init.c
index c26ab135ab..157d6706a6 100644
--- a/ext/socket/init.c
+++ b/ext/socket/init.c
@@ -508,11 +508,30 @@ wait_connectable(int fd)
int sockerr, revents;
socklen_t sockerrlen;
- /* only to clear pending error */
sockerrlen = (socklen_t)sizeof(sockerr);
if (getsockopt(fd, SOL_SOCKET, SO_ERROR, (void *)&sockerr, &sockerrlen) < 0)
return -1;
+ /* necessary for non-blocking sockets (at least ECONNREFUSED) */
+ switch (sockerr) {
+ case 0:
+ break;
+#ifdef EALREADY
+ case EALREADY:
+#endif
+#ifdef EISCONN
+ case EISCONN:
+#endif
+#ifdef ECONNREFUSED
+ case ECONNREFUSED:
+#endif
+#ifdef EHOSTUNREACH
+ case EHOSTUNREACH:
+#endif
+ errno = sockerr;
+ return -1;
+ }
+
/*
* Stevens book says, successful finish turn on RB_WAITFD_OUT and
* failure finish turn on both RB_WAITFD_IN and RB_WAITFD_OUT.