diff options
author | usa <usa@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2004-09-07 03:52:15 +0000 |
---|---|---|
committer | usa <usa@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2004-09-07 03:52:15 +0000 |
commit | f4d60b5f6370651978316dcecf8160781190f91f (patch) | |
tree | 06771a9d092ce8afad5105d6394882ff65c60b74 /ext/socket | |
parent | 70f8c054b2dad9f7f5af7444fa98bfac541b216b (diff) | |
download | ruby-f4d60b5f6370651978316dcecf8160781190f91f.tar.gz |
* {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.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@6863 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'ext/socket')
-rw-r--r-- | ext/socket/socket.c | 49 |
1 files changed, 42 insertions, 7 deletions
diff --git a/ext/socket/socket.c b/ext/socket/socket.c index 0f4ffdd2b2..ffa49fbc03 100644 --- a/ext/socket/socket.c +++ b/ext/socket/socket.c @@ -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 @@ -794,15 +800,36 @@ 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)) + errno = sockerr; + return -1; + } + } + + return 0; } #ifdef __CYGWIN__ @@ -835,7 +862,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 @@ -884,7 +915,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 |