summaryrefslogtreecommitdiff
path: root/ext/socket/socket.c
diff options
context:
space:
mode:
authorusa <usa@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2004-09-07 03:52:15 +0000
committerusa <usa@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2004-09-07 03:52:15 +0000
commitf4d60b5f6370651978316dcecf8160781190f91f (patch)
tree06771a9d092ce8afad5105d6394882ff65c60b74 /ext/socket/socket.c
parent70f8c054b2dad9f7f5af7444fa98bfac541b216b (diff)
* {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/socket.c')
-rw-r--r--ext/socket/socket.c49
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