* {bcc32,win32,wince}/Makefile.sub (config.h): add fcntl.

* win32/win32.[ch] (fcntl): ditto.

* win32/win32.c (rb_w32_connect): support nonblocking mode.

* ext/socket/socket.c (wait_connectable, ruby_connect): support
  nonblocking connect on various platforms.
  all changes are backported from CVS HEAD. [ruby-core:3154],
  [ruby-core:4364].


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_1_8@8005 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
usa 2005-02-21 01:08:56 +00:00
parent 6804916270
commit 5fec853229
7 changed files with 112 additions and 9 deletions

View file

@ -52,10 +52,16 @@
#ifdef HAVE_SYS_SELECT_H
#include <sys/select.h>
#endif
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
#endif
#ifdef HAVE_FCNTL_H
#include <fcntl.h>
#endif
#endif
#ifndef EWOULDBLOCK
#define EWOULDBLOCK EAGAIN
#endif
@ -755,15 +761,39 @@ ruby_socket(domain, type, proto)
return fd;
}
static void
thread_write_select(fd)
static int
wait_connectable(fd)
int fd;
{
fd_set fds;
int sockerr, sockerrlen;
fd_set fds_w;
fd_set fds_e;
FD_ZERO(&fds);
FD_SET(fd, &fds);
rb_thread_select(fd+1, 0, &fds, 0, 0);
for (;;) {
FD_ZERO(&fds_w);
FD_ZERO(&fds_e);
FD_SET(fd, &fds_w);
FD_SET(fd, &fds_e);
rb_thread_select(fd+1, 0, &fds_w, &fds_e, 0);
if (FD_ISSET(fd, &fds_w)) {
return 0;
}
else if (FD_ISSET(fd, &fds_e)) {
sockerrlen = sizeof(sockerr);
if (getsockopt(fd, SOL_SOCKET, SO_ERROR, (void *)&sockerr,
&sockerrlen) == 0) {
if (sockerr == 0)
continue; /* workaround for winsock */
errno = sockerr;
}
return -1;
}
}
return 0;
}
#ifdef __CYGWIN__
@ -796,7 +826,11 @@ ruby_connect(fd, sockaddr, len, socks)
#endif
#if defined(HAVE_FCNTL)
# if defined(F_GETFL)
mode = fcntl(fd, F_GETFL, 0);
# else
mode = 0;
# endif
#ifdef O_NDELAY
# define NONBLOCKING O_NDELAY
@ -845,7 +879,11 @@ ruby_connect(fd, sockaddr, len, socks)
#if WAIT_IN_PROGRESS > 0
wait_in_progress = WAIT_IN_PROGRESS;
#endif
thread_write_select(fd);
status = wait_connectable(fd);
if (status) {
break;
}
errno = 0;
continue;
#if WAIT_IN_PROGRESS > 0