diff options
author | Corinna Vinschen <corinna@vinschen.de> | 2011-08-23 18:05:04 +0400 |
---|---|---|
committer | Corinna Vinschen <corinna@vinschen.de> | 2011-08-23 18:05:04 +0400 |
commit | 58ef30a4e7b8409a5a225e2a82a93cbbdd19216d (patch) | |
tree | e41e039c45a1d1ada5b33ca6b6707eadeccb52fd /winsup/cygwin/poll.cc | |
parent | 247caa48ea1f6f16622ad384fcaefb488de04c56 (diff) |
* poll.cc (poll): Don't return prematurely if invalid fds have been
encountered. Enforce timeout set to 0 in case of invalid fds. Take
number of invalid fds into account when returning.
Diffstat (limited to 'winsup/cygwin/poll.cc')
-rw-r--r-- | winsup/cygwin/poll.cc | 25 |
1 files changed, 18 insertions, 7 deletions
diff --git a/winsup/cygwin/poll.cc b/winsup/cygwin/poll.cc index 3c342adfd..ea86ab5aa 100644 --- a/winsup/cygwin/poll.cc +++ b/winsup/cygwin/poll.cc @@ -28,6 +28,7 @@ extern "C" int poll (struct pollfd *fds, nfds_t nfds, int timeout) { int max_fd = 0; + int invalid_fds = 0; fd_set *read_fds, *write_fds, *except_fds; struct timeval tv = { timeout / 1000, (timeout % 1000) * 1000 }; @@ -51,7 +52,6 @@ poll (struct pollfd *fds, nfds_t nfds, int timeout) memset (write_fds, 0, fds_size); memset (except_fds, 0, fds_size); - int invalid_fds = 0; for (unsigned int i = 0; i < nfds; ++i) { fds[i].revents = 0; @@ -71,20 +71,31 @@ poll (struct pollfd *fds, nfds_t nfds, int timeout) } } - if (invalid_fds) - return invalid_fds; + /* Invalid fds? */ + if (invalid_fds > 0) + { + /* Only invalid fds? Return. */ + if ((nfds_t) invalid_fds == nfds) + return invalid_fds; + /* POSIX doesn't explicitely define this behaviour, but on Linux, + the timeout is set to 0 if an error occurs, and POLLNVAL is one + of these errors. So, for Linux-compatibility's sake... */ + tv.tv_sec = tv.tv_usec = 0; + } int ret = cygwin_select (max_fd + 1, read_fds, write_fds, except_fds, timeout < 0 ? NULL : &tv); + /* timeout, signal, whatever? Return. If invalid fds exist, return with + their number. */ if (ret <= 0) - return ret; + return invalid_fds ?: ret; /* Set revents fields and count fds with non-zero revents fields for return value. */ ret = 0; for (unsigned int i = 0; i < nfds; ++i) { - if (fds[i].fd >= 0) + if (fds[i].fd >= 0 && fds[i].revents != POLLNVAL) { fhandler_socket *sock; @@ -123,8 +134,8 @@ poll (struct pollfd *fds, nfds_t nfds, int timeout) ++ret; } } - - return ret; + /* Number of fds with event includes the invalid fds. */ + return ret + invalid_fds; } extern "C" int |