diff options
author | Corinna Vinschen <corinna@vinschen.de> | 2006-07-31 14:27:56 +0000 |
---|---|---|
committer | Corinna Vinschen <corinna@vinschen.de> | 2006-07-31 14:27:56 +0000 |
commit | b23bc8c33cfd5ca607bcc07deaee616f9dceff35 (patch) | |
tree | cfe39a0f9f66fb4b1b739674566bbea7570bdb5f /winsup/cygwin/poll.cc | |
parent | 1f7dbb011a3f08cac45fdda1b4a80d2abc262dcc (diff) | |
download | cygnal-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.cc | 44 |
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 ()) |