summaryrefslogtreecommitdiffstats
path: root/lib/libpthread/uthread
diff options
context:
space:
mode:
authorbrad <brad@openbsd.org>2004-01-03 07:35:10 +0000
committerbrad <brad@openbsd.org>2004-01-03 07:35:10 +0000
commit7f1df31d66a13c3c6d7f7936748f76a5ee5a679c (patch)
tree638605dedfe2755fa38f2973229bb6673044d7e2 /lib/libpthread/uthread
parentsync the list of acceptable getopt_long options with reality. (diff)
downloadwireguard-openbsd-7f1df31d66a13c3c6d7f7936748f76a5ee5a679c.tar.xz
wireguard-openbsd-7f1df31d66a13c3c6d7f7936748f76a5ee5a679c.zip
Fixes from FreeBSD's libc_r
rev 1.21 Make the libc_r version of select() set the readable or writable file descriptor bit if poll() returns POLLERR, POLLHUP, or POLLNVAL. Othewise, it's possible for select() to return successfully but with no bits set. rev 1.19 Return correct number of total bits set in all fd_set's. Change case of POLLNVAL as an error. Remove POLLHUP and POLLERR from one case, their place is most likely amongst read events. ok marc@
Diffstat (limited to 'lib/libpthread/uthread')
-rw-r--r--lib/libpthread/uthread/uthread_select.c40
1 files changed, 26 insertions, 14 deletions
diff --git a/lib/libpthread/uthread/uthread_select.c b/lib/libpthread/uthread/uthread_select.c
index 112e07eb233..acc5d3017ae 100644
--- a/lib/libpthread/uthread/uthread_select.c
+++ b/lib/libpthread/uthread/uthread_select.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uthread_select.c,v 1.10 2004/01/01 08:19:33 brad Exp $ */
+/* $OpenBSD: uthread_select.c,v 1.11 2004/01/03 07:35:10 brad Exp $ */
/*
* Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
* All rights reserved.
@@ -57,7 +57,7 @@ select(int numfds, fd_set * readfds, fd_set * writefds,
struct pthread *curthread = _get_curthread();
struct timespec ts;
int bit, i, j, ret = 0, f_wait = 1;
- int events, got_one = 0, fd_count = 0;
+ int events, got_events = 0, fd_count = 0;
struct pthread_poll_data data;
fd_mask mask, rmask, wmask, emask;
@@ -183,21 +183,34 @@ select(int numfds, fd_set * readfds, fd_set * writefds,
* this file descriptor from the fdset if
* the requested event wasn't ready.
*/
- got_one = 0;
+
+ /*
+ * First check for invalid descriptor.
+ * If found, set errno and return -1.
+ */
+ if (data.fds[i].revents & POLLNVAL) {
+ errno = EBADF;
+ ret = -1;
+ goto done;
+ }
+
+ got_events = 0;
if (readfds != NULL) {
if (FD_ISSET(data.fds[i].fd, readfds)) {
- if (data.fds[i].revents & (POLLIN |
- POLLRDNORM))
- got_one = 1;
+ if ((data.fds[i].revents & (POLLIN
+ | POLLRDNORM | POLLERR
+ | POLLHUP)) != 0)
+ got_events++;
else
FD_CLR(data.fds[i].fd, readfds);
}
}
if (writefds != NULL) {
if (FD_ISSET(data.fds[i].fd, writefds)) {
- if (data.fds[i].revents & (POLLOUT |
- POLLWRNORM | POLLWRBAND))
- got_one = 1;
+ if ((data.fds[i].revents & (POLLOUT
+ | POLLWRNORM | POLLWRBAND | POLLERR
+ | POLLHUP)) != 0)
+ got_events++;
else
FD_CLR(data.fds[i].fd,
writefds);
@@ -206,16 +219,15 @@ select(int numfds, fd_set * readfds, fd_set * writefds,
if (exceptfds != NULL) {
if (FD_ISSET(data.fds[i].fd, exceptfds)) {
if (data.fds[i].revents & (POLLRDBAND |
- POLLPRI | POLLHUP | POLLERR |
- POLLNVAL))
- got_one = 1;
+ POLLPRI))
+ got_events++;
else
FD_CLR(data.fds[i].fd,
exceptfds);
}
}
- if (got_one)
- numfds++;
+ if (got_events != 0)
+ numfds+=got_events;
}
ret = numfds;
}