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
This commit is contained in:
normal 2018-11-08 03:27:16 +00:00
parent 17e9667fe9
commit 86dca76ef2

View File

@ -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.