* fhandler_socket.cc (fhandler_socket::recv_internal): Fix a problem
with poll(2) after shutdown(SHUT_RD) has been called on the local side. * poll.cc (poll): Use POSIX type nfds_t for second parameter. Drop special socket handling for POLLIN. Add comment to explain why. * include/sys/poll.h: Declare nfds_t. Use as type for second parameter in poll(2) declaration.
This commit is contained in:
parent
1f7dbb011a
commit
b23bc8c33c
|
@ -1,3 +1,12 @@
|
|||
2006-07-31 Corinna Vinschen <corinna@vinschen.de>
|
||||
|
||||
* fhandler_socket.cc (fhandler_socket::recv_internal): Fix a problem
|
||||
with poll(2) after shutdown(SHUT_RD) has been called on the local side.
|
||||
* poll.cc (poll): Use POSIX type nfds_t for second parameter. Drop
|
||||
special socket handling for POLLIN. Add comment to explain why.
|
||||
* include/sys/poll.h: Declare nfds_t. Use as type for second parameter
|
||||
in poll(2) declaration.
|
||||
|
||||
2006-07-31 Corinna Vinschen <corinna@vinschen.de>
|
||||
|
||||
* fhandler_socket.cc (fhandler_socket::evaluate_events): Circumvent
|
||||
|
|
|
@ -1160,7 +1160,8 @@ fhandler_socket::recv_internal (WSABUF *wsabuf, DWORD wsacnt, DWORD flags,
|
|||
/* Note: Don't call WSARecvFrom(MSG_PEEK) without actually having data
|
||||
waiting in the buffers, otherwise the event handling gets messed up
|
||||
for some reason. */
|
||||
while (!(res = wait_for_events (evt_mask | FD_CLOSE)))
|
||||
while (!(res = wait_for_events (evt_mask | FD_CLOSE))
|
||||
|| saw_shutdown_read ())
|
||||
{
|
||||
res = WSARecvFrom (get_socket (), wsabuf, wsacnt, &ret,
|
||||
&flags, from, fromlen, NULL, NULL);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* sys/poll.h
|
||||
|
||||
Copyright 2000, 2001 Red Hat, Inc.
|
||||
Copyright 2000, 2001, 2006 Red Hat, Inc.
|
||||
|
||||
This file is part of Cygwin.
|
||||
|
||||
|
@ -36,7 +36,9 @@ struct pollfd {
|
|||
short revents;
|
||||
};
|
||||
|
||||
extern int poll __P ((struct pollfd *fds, unsigned int nfds, int timeout));
|
||||
typedef unsigned int nfds_t;
|
||||
|
||||
extern int poll __P ((struct pollfd *fds, nfds_t nfds, int timeout));
|
||||
|
||||
__END_DECLS
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
#include "sigproc.h"
|
||||
|
||||
extern "C" int
|
||||
poll (struct pollfd *fds, unsigned int nfds, int timeout)
|
||||
poll (struct pollfd *fds, nfds_t nfds, int timeout)
|
||||
{
|
||||
int max_fd = 0;
|
||||
fd_set *read_fds, *write_fds, *except_fds;
|
||||
|
@ -90,39 +90,15 @@ poll (struct pollfd *fds, unsigned int nfds, int timeout)
|
|||
fhandler_socket *sock;
|
||||
|
||||
if (FD_ISSET(fds[i].fd, read_fds))
|
||||
{
|
||||
char peek[1];
|
||||
sock = cygheap->fdtab[fds[i].fd]->is_socket ();
|
||||
if (!sock)
|
||||
fds[i].revents |= POLLIN;
|
||||
else if (sock->listener ())
|
||||
{
|
||||
fds[i].revents |= POLLIN;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The following action can change errno. We have to
|
||||
reset it to it's old value. */
|
||||
int old_errno = get_errno ();
|
||||
switch (sock->recvfrom (peek, sizeof (peek), MSG_PEEK,
|
||||
NULL, NULL))
|
||||
{
|
||||
case -1:
|
||||
fds[i].revents |= POLLERR;
|
||||
break;
|
||||
case 0: /* Closed on the read side... */
|
||||
/* ...or shutdown(SHUT_WR) on the write side.
|
||||
We set revents to POLLHUP until 1.5.18, but
|
||||
this is semantically borderline. */
|
||||
fds[i].revents |= POLLIN;
|
||||
break;
|
||||
default:
|
||||
fds[i].revents |= POLLIN;
|
||||
break;
|
||||
}
|
||||
set_errno (old_errno);
|
||||
}
|
||||
}
|
||||
/* This should be sufficient for sockets, too. Using
|
||||
MSG_PEEK, as before, can be considered dangerous at
|
||||
best. Quote from W. Richard Stevens: "The presence
|
||||
of an error can be considered either normal data or
|
||||
an error (POLLERR). In either case, a subsequent read
|
||||
will return -1 with errno set to the appropriate value."
|
||||
So it looks like there's actually no good reason to
|
||||
return POLLERR. */
|
||||
fds[i].revents |= POLLIN;
|
||||
/* Handle failed connect. */
|
||||
if (FD_ISSET(fds[i].fd, write_fds)
|
||||
&& (sock = cygheap->fdtab[fds[i].fd]->is_socket ())
|
||||
|
|
Loading…
Reference in New Issue