diff options
-rw-r--r-- | lang/ruby18/files/patch-ext_socket_socket.c | 105 |
1 files changed, 105 insertions, 0 deletions
diff --git a/lang/ruby18/files/patch-ext_socket_socket.c b/lang/ruby18/files/patch-ext_socket_socket.c new file mode 100644 index 000000000000..86092a459d58 --- /dev/null +++ b/lang/ruby18/files/patch-ext_socket_socket.c @@ -0,0 +1,105 @@ +--- ext/socket/socket.c.orig 2009-02-23 00:54:12.000000000 +0300 ++++ ext/socket/socket.c 2009-02-23 01:27:13.000000000 +0300 +@@ -1111,81 +1111,33 @@ + fcntl(fd, F_SETFL, mode|NONBLOCKING); + #endif /* HAVE_FCNTL */ + +- for (;;) { + #if defined(SOCKS) && !defined(SOCKS5) +- if (socks) { +- status = Rconnect(fd, sockaddr, len); +- } +- else +-#endif +- { +- status = connect(fd, sockaddr, len); +- } +- if (status < 0) { +- switch (errno) { +- case EAGAIN: +-#ifdef EINPROGRESS +- case EINPROGRESS: +-#endif +-#if WAIT_IN_PROGRESS > 0 +- sockerrlen = sizeof(sockerr); +- status = getsockopt(fd, SOL_SOCKET, SO_ERROR, (void *)&sockerr, &sockerrlen); +- if (status) break; +- if (sockerr) { +- status = -1; +- errno = sockerr; +- break; +- } +-#endif +-#ifdef EALREADY +- case EALREADY: +-#endif +-#if WAIT_IN_PROGRESS > 0 +- wait_in_progress = WAIT_IN_PROGRESS; +-#endif +- status = wait_connectable(fd); +- if (status) { +- break; +- } +- errno = 0; +- continue; +- +-#if WAIT_IN_PROGRESS > 0 +- case EINVAL: +- if (wait_in_progress-- > 0) { +- /* +- * connect() after EINPROGRESS returns EINVAL on +- * some platforms, need to check true error +- * status. +- */ +- sockerrlen = sizeof(sockerr); +- status = getsockopt(fd, SOL_SOCKET, SO_ERROR, (void *)&sockerr, &sockerrlen); +- if (!status && !sockerr) { +- struct timeval tv = {0, 100000}; +- rb_thread_wait_for(tv); +- continue; +- } +- status = -1; +- errno = sockerr; +- } +- break; +-#endif +- +-#ifdef EISCONN +- case EISCONN: +- status = 0; +- errno = 0; +- break; ++ if (socks) { ++ status = Rconnect(fd, sockaddr, len); ++ } ++ else + #endif +- default: +- break; ++ { ++ status = connect(fd, sockaddr, len); ++ } ++ ++ if (status < 0 && (errno == EINPROGRESS || errno == EWOULDBLOCK)) { ++ status = wait_connectable(fd); ++ if (status == 0) { ++ int buf; ++ char c; ++ int len = sizeof(buf); ++ status = getpeername(fd, (struct sockaddr *)&buf, &len); ++ if (status == -1) { ++ read(fd, &c, 1); /* set errno. */ + } + } ++ } ++ + #ifdef HAVE_FCNTL +- fcntl(fd, F_SETFL, mode); ++ fcntl(fd, F_SETFL, mode); + #endif +- return status; +- } ++ return status; + } + + struct inetsock_arg |