* ext/socket/socket.c (ruby_connect): connect() after EINPROGRESS

returns EINVAL on some platforms, need to check true error
  status.  [ruby-core:01037]


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@3809 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
nobu 2003-05-16 15:18:14 +00:00
parent 6cbcafb9b9
commit e9d1dd8388
2 changed files with 43 additions and 16 deletions

View File

@ -1,3 +1,9 @@
Sat May 17 00:18:11 2003 Nobuyoshi Nakada <nobu.nokada@softhome.net>
* ext/socket/socket.c (ruby_connect): connect() after EINPROGRESS
returns EINVAL on some platforms, need to check true error
status. [ruby-core:01037]
Fri May 16 12:40:40 2003 Yukihiro Matsumoto <matz@ruby-lang.org> Fri May 16 12:40:40 2003 Yukihiro Matsumoto <matz@ruby-lang.org>
* eval.c (block_pass): chain previous block to the pushing block. * eval.c (block_pass): chain previous block to the pushing block.

View File

@ -724,6 +724,13 @@ thread_write_select(fd)
rb_thread_select(fd+1, 0, &fds, 0, 0); rb_thread_select(fd+1, 0, &fds, 0, 0);
} }
#ifdef __CYGWIN__
#define WAIT_IN_PROGRESS 10
#endif
#ifdef __APPLE__
#define WAIT_IN_PROGRESS 10
#endif
static int static int
ruby_connect(fd, sockaddr, len, socks) ruby_connect(fd, sockaddr, len, socks)
int fd; int fd;
@ -733,7 +740,7 @@ ruby_connect(fd, sockaddr, len, socks)
{ {
int status; int status;
int mode; int mode;
#if defined __CYGWIN__ #ifdef WAIT_IN_PROGRESS
int wait_in_progress = -1; int wait_in_progress = -1;
#endif #endif
@ -770,21 +777,35 @@ ruby_connect(fd, sockaddr, len, socks)
case EAGAIN: case EAGAIN:
#ifdef EINPROGRESS #ifdef EINPROGRESS
case EINPROGRESS: case EINPROGRESS:
#ifdef __CYGWIN__
case EALREADY:
wait_in_progress = 10;
#endif #endif
#ifdef EALREADY
case EALREADY:
#endif
#ifdef WAIT_IN_PROGRESS
wait_in_progress = WAIT_IN_PROGRESS;
#endif #endif
thread_write_select(fd); thread_write_select(fd);
continue; continue;
#if defined __CYGWIN__ #ifdef WAIT_IN_PROGRESS
case EINVAL: case EINVAL:
if (wait_in_progress-- > 0) { if (wait_in_progress-- > 0) {
int sockerr, sockerrlen = sizeof(sockerr);
/*
* connect() after EINPROGRESS returns EINVAL on
* some platforms, need to check true error
* status.
*/
status = getsockopt(fd, SOL_SOCKET, SO_ERROR, &sockerr, &sockerrlen);
if (!status && !sockerr) {
struct timeval tv = {0, 100000}; struct timeval tv = {0, 100000};
rb_thread_wait_for(tv); rb_thread_wait_for(tv);
continue; continue;
} }
status = -1;
errno = sockerr;
}
break; break;
#endif #endif