diff options
author | nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2003-08-20 07:44:53 +0000 |
---|---|---|
committer | nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2003-08-20 07:44:53 +0000 |
commit | b1f01153943b95019ecc56192527e9fb00adb240 (patch) | |
tree | 8a7234514cf4de4359851e28c0baa4456f390cfb | |
parent | 360b0a015aba72f62ea2ffee4f52ce2b9132a2d1 (diff) | |
download | ruby-b1f01153943b95019ecc56192527e9fb00adb240.tar.gz |
* ext/socket/socket.c (ruby_connect): many systems seem to have
a problem in select() after EINPROGRESS. [ruby-list:38080]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@4415 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r-- | ChangeLog | 5 | ||||
-rw-r--r-- | ext/socket/socket.c | 28 |
2 files changed, 28 insertions, 5 deletions
@@ -1,3 +1,8 @@ +Wed Aug 20 16:44:49 2003 Nobuyoshi Nakada <nobu@ruby-lang.org> + + * ext/socket/socket.c (ruby_connect): many systems seem to have + a problem in select() after EINPROGRESS. [ruby-list:38080] + Wed Aug 20 01:31:17 2003 why the lucky stiff <ruby-cvs@whytheluckystiff.net> * ext/syck/syck.h: Parser definition problems on HP-UX. [ruby-talk:79389] diff --git a/ext/socket/socket.c b/ext/socket/socket.c index 13329eedcb..2130d5f53c 100644 --- a/ext/socket/socket.c +++ b/ext/socket/socket.c @@ -731,6 +731,14 @@ thread_write_select(fd) #ifdef __APPLE__ #define WAIT_IN_PROGRESS 10 #endif +#ifdef __linux__ +/* returns correct error */ +#define WAIT_IN_PROGRESS 0 +#endif +#ifndef WAIT_IN_PROGRESS +/* BSD origin code apparently has a problem */ +#define WAIT_IN_PROGRESS 1 +#endif static int ruby_connect(fd, sockaddr, len, socks) @@ -741,8 +749,9 @@ ruby_connect(fd, sockaddr, len, socks) { int status; int mode; -#ifdef WAIT_IN_PROGRESS +#if WAIT_IN_PROGRESS > 0 int wait_in_progress = -1; + int sockerr, sockerrlen; #endif #if defined(HAVE_FCNTL) @@ -779,25 +788,34 @@ ruby_connect(fd, sockaddr, len, socks) #ifdef EINPROGRESS case EINPROGRESS: #endif +#if WAIT_IN_PROGRESS > 0 + sockerrlen = sizeof(sockerr); + status = getsockopt(fd, SOL_SOCKET, SO_ERROR, &sockerr, &sockerrlen); + if (status) break; + if (sockerr) { + status = -1; + errno = sockerr; + break; + } +#endif #ifdef EALREADY case EALREADY: #endif -#ifdef WAIT_IN_PROGRESS +#if WAIT_IN_PROGRESS > 0 wait_in_progress = WAIT_IN_PROGRESS; #endif thread_write_select(fd); continue; -#ifdef WAIT_IN_PROGRESS +#if WAIT_IN_PROGRESS > 0 case EINVAL: if (wait_in_progress-- > 0) { - int sockerr, sockerrlen = sizeof(sockerr); - /* * connect() after EINPROGRESS returns EINVAL on * some platforms, need to check true error * status. */ + sockerrlen = sizeof(sockerr); status = getsockopt(fd, SOL_SOCKET, SO_ERROR, &sockerr, &sockerrlen); if (!status && !sockerr) { struct timeval tv = {0, 100000}; |