Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--winsup/cygwin/ChangeLog11
-rw-r--r--winsup/cygwin/fhandler.h2
-rw-r--r--winsup/cygwin/fhandler_socket.cc28
-rw-r--r--winsup/cygwin/net.cc51
4 files changed, 37 insertions, 55 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index 3cdf7251e..e2897b750 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,5 +1,16 @@
2005-10-22 Corinna Vinschen <corinna@vinschen.de>
+ * fhandler.h (class fhandler_socket): Add timeout parameter to wait()
+ method.
+ * fhandler_socket.cc (fhandler_socket::connect): Use event driven
+ technique (prepare/wait/release) to implement interuptible connect.
+ (fhandler_socket::wait): Add timeout parameter. Allow FD_CONNECT
+ handling.
+ * net.cc (cygwin_connect): Remove braindead workaround for allowing
+ blocking connect. That's entirely in fhandler_socket::connect now.
+
+2005-10-22 Corinna Vinschen <corinna@vinschen.de>
+
* include/cygwin/version.h: Fix typo.
2005-10-21 Christopher Faylor <cgf@timesys.com>
diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h
index 961aabc6c..b45d82ff4 100644
--- a/winsup/cygwin/fhandler.h
+++ b/winsup/cygwin/fhandler.h
@@ -425,7 +425,7 @@ class fhandler_socket: public fhandler_base
} status;
bool prepare (HANDLE &event, long event_mask);
- int wait (HANDLE event, int flags);
+ int wait (HANDLE event, int flags, DWORD timeout = 10);
void release (HANDLE event);
public:
diff --git a/winsup/cygwin/fhandler_socket.cc b/winsup/cygwin/fhandler_socket.cc
index 420eb627a..f9b913729 100644
--- a/winsup/cygwin/fhandler_socket.cc
+++ b/winsup/cygwin/fhandler_socket.cc
@@ -681,7 +681,20 @@ fhandler_socket::connect (const struct sockaddr *name, int namelen)
return -1;
}
- res = ::connect (get_socket (), (struct sockaddr *) &sin, namelen);
+ if (is_nonblocking ())
+ res = ::connect (get_socket (), (struct sockaddr *) &sin, namelen);
+ else
+ {
+ HANDLE evt;
+ if (prepare (evt, FD_CONNECT))
+ {
+ res = ::connect (get_socket (), (struct sockaddr *) &sin, namelen);
+ if (res == SOCKET_ERROR
+ && WSAGetLastError () == WSAEWOULDBLOCK)
+ res = wait (evt, 0, INFINITE);
+ release (evt);
+ }
+ }
if (!res)
err = 0;
@@ -877,14 +890,14 @@ fhandler_socket::prepare (HANDLE &event, long event_mask)
}
int
-fhandler_socket::wait (HANDLE event, int flags)
+fhandler_socket::wait (HANDLE event, int flags, DWORD timeout)
{
int ret = SOCKET_ERROR;
int wsa_err = 0;
WSAEVENT ev[2] = { event, signal_arrived };
WSANETWORKEVENTS evts;
- switch (WSAWaitForMultipleEvents (2, ev, FALSE, 10, FALSE))
+ switch (WSAWaitForMultipleEvents (2, ev, FALSE, timeout, FALSE))
{
case WSA_WAIT_TIMEOUT:
ret = 0;
@@ -910,7 +923,14 @@ fhandler_socket::wait (HANDLE event, int flags)
break;
}
}
- if (evts.lNetworkEvents & FD_READ)
+ if (evts.lNetworkEvents & FD_CONNECT)
+ {
+ if (evts.iErrorCode[FD_CONNECT_BIT])
+ wsa_err = evts.iErrorCode[FD_CONNECT_BIT];
+ else
+ ret = 0;
+ }
+ else if (evts.lNetworkEvents & FD_READ)
{
if (evts.iErrorCode[FD_READ_BIT])
wsa_err = evts.iErrorCode[FD_READ_BIT];
diff --git a/winsup/cygwin/net.cc b/winsup/cygwin/net.cc
index 91ee74a20..eccf0635f 100644
--- a/winsup/cygwin/net.cc
+++ b/winsup/cygwin/net.cc
@@ -775,56 +775,7 @@ cygwin_connect (int fd, const struct sockaddr *name, int namelen)
if (efault.faulted (EFAULT) || !fh)
res = -1;
else
- {
- bool was_blocking = false;
- if (!fh->is_nonblocking ())
- {
- int nonblocking = 1;
- fh->ioctl (FIONBIO, &nonblocking);
- was_blocking = true;
- }
- res = fh->connect (name, namelen);
- if (was_blocking)
- {
- if (res == -1 && get_errno () == EINPROGRESS)
- {
- size_t fds_size = howmany (fd + 1, NFDBITS) * sizeof (fd_mask);
- fd_set *write_fds = (fd_set *) alloca (fds_size);
- fd_set *except_fds = (fd_set *) alloca (fds_size);
- memset (write_fds, 0, fds_size);
- memset (except_fds, 0, fds_size);
- FD_SET (fd, write_fds);
- FD_SET (fd, except_fds);
- res = cygwin_select (fd + 1, NULL, write_fds, except_fds, NULL);
- if (res > 0 && FD_ISSET (fd, except_fds))
- {
- res = -1;
- for (;;)
- {
- int err;
- int len = sizeof err;
- cygwin_getsockopt (fd, SOL_SOCKET, SO_ERROR,
- (void *) &err, &len);
- if (err)
- {
- set_errno (err);
- break;
- }
- low_priority_sleep (0);
- }
- }
- else if (res > 0)
- res = 0;
- else
- {
- WSASetLastError (WSAEINPROGRESS);
- set_winsock_errno ();
- }
- }
- int nonblocking = 0;
- fh->ioctl (FIONBIO, &nonblocking);
- }
- }
+ res = fh->connect (name, namelen);
syscall_printf ("%d = connect (%d, %p, %d)", res, fd, name, namelen);