summaryrefslogtreecommitdiffstats
path: root/winsup
diff options
context:
space:
mode:
Diffstat (limited to 'winsup')
-rw-r--r--winsup/cygwin/ChangeLog16
-rw-r--r--winsup/cygwin/fhandler_socket.cc27
-rw-r--r--winsup/cygwin/poll.cc7
-rw-r--r--winsup/cygwin/select.cc44
4 files changed, 50 insertions, 44 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index c18b33f09..23aa6dc11 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,3 +1,19 @@
+2006-07-27 Corinna Vinschen <corinna@vinschen.de>
+
+ * fhandler_socket.cc: Revert misguided attempt to handle FD_CLOSE error
+ conditions in evaluate_events.
+ (search_wsa_event_slot): Move wrongly placed memset in
+ fhandler_socket::init_events here.
+ (fhandler_socket::init_events): Initially set FD_WRITE event for
+ connectionless sockets.
+ * poll.cc (poll): Don't add sockets always to except_fds since select
+ is now supposed to do it right.
+ * select.cc (set_bits): Set connection state correctly for failed
+ af_local_connect on local sockets. Remove socket special handling
+ for except_selected descriptors.
+ (peek_socket): Try to set the read/write/exception bits actually
+ correctly.
+
2006-07-27 Brian Ford <Brian.Ford@FlightSafety.com>
* fhandler_socket.cc (fhandler_socket::recvmsg): Remove unused tot
diff --git a/winsup/cygwin/fhandler_socket.cc b/winsup/cygwin/fhandler_socket.cc
index 760dbc456..4a5177a02 100644
--- a/winsup/cygwin/fhandler_socket.cc
+++ b/winsup/cygwin/fhandler_socket.cc
@@ -386,7 +386,7 @@ struct wsa_event
{
LONG serial_number;
long events;
- int errorcode;
+ int connect_errorcode;
pid_t owner;
};
@@ -443,6 +443,7 @@ search_wsa_event_slot (LONG new_serial_number)
return NULL;
}
}
+ memset (&wsa_events[slot], 0, sizeof (wsa_event));
wsa_events[slot].serial_number = new_serial_number;
ReleaseMutex (wsa_slot_mtx);
return wsa_events + slot;
@@ -490,7 +491,9 @@ fhandler_socket::init_events ()
return false;
}
wsock_events = search_wsa_event_slot (new_serial_number);
- memset (wsock_events, 0, sizeof *wsock_events);
+ /* sock type not yet set here. */
+ if (pc.dev == FH_UDP || pc.dev == FH_DGRAM)
+ wsock_events->events = FD_WRITE;
return true;
}
@@ -508,9 +511,7 @@ fhandler_socket::evaluate_events (const long event_mask, long &events,
LOCK_EVENTS;
wsock_events->events |= evts.lNetworkEvents;
if (evts.lNetworkEvents & FD_CONNECT)
- wsock_events->errorcode = evts.iErrorCode[FD_CONNECT_BIT];
- else if (evts.lNetworkEvents & FD_CLOSE)
- wsock_events->errorcode = evts.iErrorCode[FD_CLOSE_BIT];
+ wsock_events->connect_errorcode = evts.iErrorCode[FD_CONNECT_BIT];
UNLOCK_EVENTS;
if ((evts.lNetworkEvents & FD_OOB) && wsock_events->owner)
kill (wsock_events->owner, SIGURG);
@@ -520,22 +521,18 @@ fhandler_socket::evaluate_events (const long event_mask, long &events,
LOCK_EVENTS;
if ((events = (wsock_events->events & event_mask)) != 0)
{
- if (events & (FD_CONNECT | FD_CLOSE))
+ if (events & FD_CONNECT)
{
int wsa_err = 0;
- if ((wsa_err = wsock_events->errorcode) != 0)
+ if ((wsa_err = wsock_events->connect_errorcode) != 0)
{
WSASetLastError (wsa_err);
ret = SOCKET_ERROR;
}
- if (events & FD_CONNECT)
- {
- if (!wsock_events->errorcode)
- wsock_events->events |= FD_WRITE;
- wsock_events->events &= ~FD_CONNECT;
- }
- if (!(events & FD_CLOSE))
- wsock_events->errorcode = 0;
+ else
+ wsock_events->events |= FD_WRITE;
+ wsock_events->events &= ~FD_CONNECT;
+ wsock_events->connect_errorcode = 0;
}
if (erase)
wsock_events->events &= ~(events & ~(FD_WRITE | FD_CLOSE));
diff --git a/winsup/cygwin/poll.cc b/winsup/cygwin/poll.cc
index 3ce46fab6..a7db49ef8 100644
--- a/winsup/cygwin/poll.cc
+++ b/winsup/cygwin/poll.cc
@@ -1,6 +1,6 @@
/* poll.cc. Implements poll(2) via usage of select(2) call.
- Copyright 2000, 2001, 2002, 2003, 2004, 2005 Red Hat, Inc.
+ Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006 Red Hat, Inc.
This file is part of Cygwin.
@@ -63,9 +63,7 @@ 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);
- /* On sockets, except_fds is needed to catch failed connects. */
- if ((fds[i].events & POLLPRI)
- || cygheap->fdtab[fds[i].fd]->is_socket ())
+ if (fds[i].events & POLLPRI)
FD_SET(fds[i].fd, except_fds);
}
else if (fds[i].fd >= 0)
@@ -127,7 +125,6 @@ poll (struct pollfd *fds, unsigned int nfds, int timeout)
}
/* 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);
diff --git a/winsup/cygwin/select.cc b/winsup/cygwin/select.cc
index abfe9e5a3..e5b50d375 100644
--- a/winsup/cygwin/select.cc
+++ b/winsup/cygwin/select.cc
@@ -364,22 +364,20 @@ set_bits (select_record *me, fd_set *readfds, fd_set *writefds,
{
/* Special AF_LOCAL handling. */
if (!me->read_ready && sock->connect_state () == connect_pending
- && sock->af_local_connect () && me->read_selected)
- UNIX_FD_SET (me->fd, readfds);
- sock->connect_state (connected);
+ && sock->af_local_connect ())
+ {
+ if (me->read_selected)
+ UNIX_FD_SET (me->fd, readfds);
+ sock->connect_state (connect_failed);
+ }
+ else
+ sock->connect_state (connected);
}
ready++;
}
- if ((me->except_selected || me->except_on_write) && me->except_ready)
+ if (me->except_selected && me->except_ready)
{
- if (me->except_on_write) /* Only on sockets */
- {
- UNIX_FD_SET (me->fd, writefds);
- if ((sock = me->fh->is_socket ()))
- sock->connect_state (connect_failed);
- }
- if (me->except_selected)
- UNIX_FD_SET (me->fd, exceptfds);
+ UNIX_FD_SET (me->fd, exceptfds);
ready++;
}
select_printf ("ready %d", ready);
@@ -1264,23 +1262,21 @@ peek_socket (select_record *me, bool)
{
fhandler_socket *fh = (fhandler_socket *) me->fh;
long events;
- long evt_mask = (FD_CLOSE
- | (me->read_selected ? (FD_READ | FD_ACCEPT) : 0)
- | (me->write_selected ? (FD_WRITE | FD_CONNECT) : 0)
- | (me->except_selected ? (FD_OOB | FD_CONNECT) : 0));
+ /* Don't play with the settings again, unless having taken a deep look into
+ Richard W. Stevens Network Programming book. Thank you. */
+ long evt_mask = (me->read_selected ? (FD_READ | FD_ACCEPT | FD_CLOSE) : 0)
+ | (me->write_selected ? (FD_WRITE | FD_CONNECT | FD_CLOSE) : 0)
+ | (me->except_selected ? FD_OOB : 0);
int ret = fh->evaluate_events (evt_mask, events, false);
if (me->read_selected)
- me->read_ready |= !!(events & (FD_READ | FD_ACCEPT | FD_CLOSE));
+ me->read_ready |= ret || !!(events & (FD_READ | FD_ACCEPT | FD_CLOSE));
if (me->write_selected)
- {
- if ((events & FD_CONNECT) && !ret)
- me->write_ready = true;
- else
- me->write_ready |= !!(events & (FD_WRITE | FD_CLOSE));
- }
+ me->write_ready |= ret || !!(events & (FD_WRITE | FD_CONNECT | FD_CLOSE));
if (me->except_selected)
- me->except_ready |= ret || !!(events & FD_OOB);
+ me->except_ready |= !!(events & FD_OOB);
+ select_printf ("read_ready: %d, write_ready: %d, except_ready: %d",
+ me->read_ready, me->write_ready, me->except_ready);
return me->read_ready || me->write_ready || me->except_ready;
}