* 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>
|
2006-07-31 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
* fhandler_socket.cc (fhandler_socket::evaluate_events): Circumvent
|
* 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
|
/* Note: Don't call WSARecvFrom(MSG_PEEK) without actually having data
|
||||||
waiting in the buffers, otherwise the event handling gets messed up
|
waiting in the buffers, otherwise the event handling gets messed up
|
||||||
for some reason. */
|
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,
|
res = WSARecvFrom (get_socket (), wsabuf, wsacnt, &ret,
|
||||||
&flags, from, fromlen, NULL, NULL);
|
&flags, from, fromlen, NULL, NULL);
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/* sys/poll.h
|
/* sys/poll.h
|
||||||
|
|
||||||
Copyright 2000, 2001 Red Hat, Inc.
|
Copyright 2000, 2001, 2006 Red Hat, Inc.
|
||||||
|
|
||||||
This file is part of Cygwin.
|
This file is part of Cygwin.
|
||||||
|
|
||||||
@ -36,7 +36,9 @@ struct pollfd {
|
|||||||
short revents;
|
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
|
__END_DECLS
|
||||||
|
|
||||||
|
@ -27,7 +27,7 @@
|
|||||||
#include "sigproc.h"
|
#include "sigproc.h"
|
||||||
|
|
||||||
extern "C" int
|
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;
|
int max_fd = 0;
|
||||||
fd_set *read_fds, *write_fds, *except_fds;
|
fd_set *read_fds, *write_fds, *except_fds;
|
||||||
@ -90,39 +90,15 @@ poll (struct pollfd *fds, unsigned int nfds, int timeout)
|
|||||||
fhandler_socket *sock;
|
fhandler_socket *sock;
|
||||||
|
|
||||||
if (FD_ISSET(fds[i].fd, read_fds))
|
if (FD_ISSET(fds[i].fd, read_fds))
|
||||||
{
|
/* This should be sufficient for sockets, too. Using
|
||||||
char peek[1];
|
MSG_PEEK, as before, can be considered dangerous at
|
||||||
sock = cygheap->fdtab[fds[i].fd]->is_socket ();
|
best. Quote from W. Richard Stevens: "The presence
|
||||||
if (!sock)
|
of an error can be considered either normal data or
|
||||||
fds[i].revents |= POLLIN;
|
an error (POLLERR). In either case, a subsequent read
|
||||||
else if (sock->listener ())
|
will return -1 with errno set to the appropriate value."
|
||||||
{
|
So it looks like there's actually no good reason to
|
||||||
fds[i].revents |= POLLIN;
|
return POLLERR. */
|
||||||
}
|
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* Handle failed connect. */
|
/* Handle failed connect. */
|
||||||
if (FD_ISSET(fds[i].fd, write_fds)
|
if (FD_ISSET(fds[i].fd, write_fds)
|
||||||
&& (sock = cygheap->fdtab[fds[i].fd]->is_socket ())
|
&& (sock = cygheap->fdtab[fds[i].fd]->is_socket ())
|
||||||
|
Loading…
x
Reference in New Issue
Block a user