summaryrefslogtreecommitdiffstats
path: root/winsup/cygwin/poll.cc
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2006-07-31 14:27:56 +0000
committerCorinna Vinschen <corinna@vinschen.de>2006-07-31 14:27:56 +0000
commitb23bc8c33cfd5ca607bcc07deaee616f9dceff35 (patch)
treecfe39a0f9f66fb4b1b739674566bbea7570bdb5f /winsup/cygwin/poll.cc
parent1f7dbb011a3f08cac45fdda1b4a80d2abc262dcc (diff)
downloadcygnal-b23bc8c33cfd5ca607bcc07deaee616f9dceff35.tar.gz
cygnal-b23bc8c33cfd5ca607bcc07deaee616f9dceff35.tar.bz2
cygnal-b23bc8c33cfd5ca607bcc07deaee616f9dceff35.zip
* 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.
Diffstat (limited to 'winsup/cygwin/poll.cc')
-rw-r--r--winsup/cygwin/poll.cc44
1 files changed, 10 insertions, 34 deletions
diff --git a/winsup/cygwin/poll.cc b/winsup/cygwin/poll.cc
index a7db49ef8..3be689c90 100644
--- a/winsup/cygwin/poll.cc
+++ b/winsup/cygwin/poll.cc
@@ -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 ())