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:
authorCorinna Vinschen <corinna@vinschen.de>2005-04-18 22:56:52 +0400
committerCorinna Vinschen <corinna@vinschen.de>2005-04-18 22:56:52 +0400
commit04843bf4a05314c57cf2036917a0e52d95b79ade (patch)
treebbca4a0ea3133a0d6fbee71d9ff7e6057e2ee8d0
parent2180b9627dbb4ef05b6205b678b36376511967e6 (diff)
* fhandler.h (enum conn_state): Add connect_failed state.
* fhandler_socket.cc (fhandler_socket::connect): Set connect_state to connect_failed when connect failed. * poll.cc (poll): Change errno to EINVAL if allocating memory fails, according to SUSv3. Add socket descriptors always to except_fds. Test for failed connect and set revents flags appropriately. * select.cc (set_bits): Set connect_state to connect_failed when select indicates failed nonblocking connect. (fhandler_dev_null::select_except): Set except_ready to false so that /dev/null is not always in except state. (peek_socket): Fix bogus conditional. (fhandler_socket::select_write): Treat all connect_states except unconnected equivalent to return consistent results. (fhandler_windows::select_except): Set except_ready to false so that /dev/windows is not always in except state.
-rw-r--r--winsup/cygwin/ChangeLog18
-rw-r--r--winsup/cygwin/fhandler.h3
-rw-r--r--winsup/cygwin/fhandler_socket.cc4
-rw-r--r--winsup/cygwin/poll.cc28
-rw-r--r--winsup/cygwin/select.cc14
5 files changed, 50 insertions, 17 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index d205c4754..a1f575ab4 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,3 +1,21 @@
+2005-04-18 Corinna Vinschen <corinna@vinschen.de>
+
+ * fhandler.h (enum conn_state): Add connect_failed state.
+ * fhandler_socket.cc (fhandler_socket::connect): Set connect_state to
+ connect_failed when connect failed.
+ * poll.cc (poll): Change errno to EINVAL if allocating memory fails,
+ according to SUSv3. Add socket descriptors always to except_fds. Test
+ for failed connect and set revents flags appropriately.
+ * select.cc (set_bits): Set connect_state to connect_failed when
+ select indicates failed nonblocking connect.
+ (fhandler_dev_null::select_except): Set except_ready to false so that
+ /dev/null is not always in except state.
+ (peek_socket): Fix bogus conditional.
+ (fhandler_socket::select_write): Treat all connect_states except
+ unconnected equivalent to return consistent results.
+ (fhandler_windows::select_except): Set except_ready to false so that
+ /dev/windows is not always in except state.
+
2005-04-18 Christopher Faylor <cgf@timesys.com>
* include/cygwin/version.h: Bump DLL minor number to 16.
diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h
index a7fcb9086..7611378bd 100644
--- a/winsup/cygwin/fhandler.h
+++ b/winsup/cygwin/fhandler.h
@@ -50,7 +50,8 @@ enum conn_state
{
unconnected = 0,
connect_pending = 1,
- connected = 2
+ connected = 2,
+ connect_failed = 3
};
enum line_edit_status
diff --git a/winsup/cygwin/fhandler_socket.cc b/winsup/cygwin/fhandler_socket.cc
index aa412081e..7c7e2daf8 100644
--- a/winsup/cygwin/fhandler_socket.cc
+++ b/winsup/cygwin/fhandler_socket.cc
@@ -706,7 +706,7 @@ fhandler_socket::connect (const struct sockaddr *name, int namelen)
err = WSAGetLastError ();
/* Special handling for connect to return the correct error code
when called on a non-blocking socket. */
- if (is_nonblocking () || connect_state () == connect_pending)
+ if (is_nonblocking ())
{
if (err == WSAEWOULDBLOCK || err == WSAEALREADY)
in_progress = true;
@@ -736,6 +736,8 @@ fhandler_socket::connect (const struct sockaddr *name, int namelen)
if (err == WSAEINPROGRESS || err == WSAEALREADY)
connect_state (connect_pending);
+ else if (err)
+ connect_state (connect_failed);
else
connect_state (connected);
diff --git a/winsup/cygwin/poll.cc b/winsup/cygwin/poll.cc
index c6a98f422..50f675372 100644
--- a/winsup/cygwin/poll.cc
+++ b/winsup/cygwin/poll.cc
@@ -45,7 +45,7 @@ poll (struct pollfd *fds, unsigned int nfds, int timeout)
if (!read_fds || !write_fds || !except_fds)
{
- set_errno (ENOMEM);
+ set_errno (EINVAL); /* According to SUSv3. */
return -1;
}
@@ -63,7 +63,9 @@ poll (struct pollfd *fds, unsigned int nfds, int timeout)
FD_SET(fds[i].fd, read_fds);
if (fds[i].events & POLLOUT)
FD_SET(fds[i].fd, write_fds);
- if (fds[i].events & POLLPRI)
+ /* On sockets, except_fds is needed to catch failed connects. */
+ if ((fds[i].events & POLLPRI)
+ || cygheap->fdtab[fds[i].fd]->is_socket ())
FD_SET(fds[i].fd, except_fds);
}
else if (fds[i].fd >= 0)
@@ -87,11 +89,12 @@ poll (struct pollfd *fds, unsigned int nfds, int timeout)
fds[i].revents = POLLHUP;
else
{
+ fhandler_socket *sock;
+
if (FD_ISSET(fds[i].fd, read_fds))
{
char peek[1];
- fhandler_socket *sock =
- cygheap->fdtab[fds[i].fd]->is_socket ();
+ sock = cygheap->fdtab[fds[i].fd]->is_socket ();
if (!sock)
fds[i].revents |= POLLIN;
else
@@ -125,10 +128,19 @@ poll (struct pollfd *fds, unsigned int nfds, int timeout)
set_errno (old_errno);
}
}
- if (FD_ISSET(fds[i].fd, write_fds))
- fds[i].revents |= POLLOUT;
- if (FD_ISSET(fds[i].fd, except_fds))
- fds[i].revents |= POLLPRI;
+ /* Handle failed connect. */
+ if (FD_ISSET(fds[i].fd, write_fds)
+ && FD_ISSET(fds[i].fd, except_fds)
+ && (sock = cygheap->fdtab[fds[i].fd]->is_socket ())
+ && sock->connect_state () == connect_failed)
+ fds[i].revents |= (POLLIN | POLLERR);
+ else
+ {
+ if (FD_ISSET(fds[i].fd, write_fds))
+ fds[i].revents |= POLLOUT;
+ if (FD_ISSET(fds[i].fd, except_fds))
+ fds[i].revents |= POLLPRI;
+ }
}
}
}
diff --git a/winsup/cygwin/select.cc b/winsup/cygwin/select.cc
index 1c469cf63..2daa88a5f 100644
--- a/winsup/cygwin/select.cc
+++ b/winsup/cygwin/select.cc
@@ -352,7 +352,7 @@ set_bits (select_record *me, fd_set *readfds, fd_set *writefds,
{
UNIX_FD_SET (me->fd, writefds);
if ((sock = me->fh->is_socket ()))
- sock->connect_state (connected);
+ sock->connect_state (connect_failed);
}
if (me->except_selected)
UNIX_FD_SET (me->fd, exceptfds);
@@ -915,7 +915,7 @@ fhandler_dev_null::select_except (select_record *s)
}
s->h = get_handle ();
s->except_selected = true;
- s->except_ready = true;
+ s->except_ready = false;
return s;
}
@@ -1271,11 +1271,11 @@ peek_socket (select_record *me, bool)
set_winsock_errno ();
return 0;
}
- if (WINSOCK_FD_ISSET (h, &ws_readfds) || (me->read_selected && me->read_ready))
+ if (WINSOCK_FD_ISSET (h, &ws_readfds))
me->read_ready = true;
- if (WINSOCK_FD_ISSET (h, &ws_writefds) || (me->write_selected && me->write_ready))
+ if (WINSOCK_FD_ISSET (h, &ws_writefds))
me->write_ready = true;
- if (WINSOCK_FD_ISSET (h, &ws_exceptfds) || ((me->except_selected || me->except_on_write) && me->except_ready))
+ if (WINSOCK_FD_ISSET (h, &ws_exceptfds))
me->except_ready = true;
}
return me->read_ready || me->write_ready || me->except_ready;
@@ -1460,7 +1460,7 @@ fhandler_socket::select_write (select_record *s)
s->peek = peek_socket;
s->write_ready = saw_shutdown_write () || connect_state () == unconnected;
s->write_selected = true;
- if (connect_state () == connect_pending)
+ if (connect_state () != unconnected)
{
s->except_ready = saw_shutdown_write () || saw_shutdown_read ();
s->except_on_write = true;
@@ -1559,7 +1559,7 @@ fhandler_windows::select_except (select_record *s)
s->peek = peek_windows;
s->h = get_handle ();
s->except_selected = true;
- s->except_ready = true;
+ s->except_ready = false;
s->windows_handle = true;
return s;
}