summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorBrad Smith <brad@cvs.openbsd.org>2004-01-03 07:35:11 +0000
committerBrad Smith <brad@cvs.openbsd.org>2004-01-03 07:35:11 +0000
commite0f87a32733320338c723c6085342f34acc87ce3 (patch)
tree31b1a85879b99ebe40739af10a43b767eb0beaac /lib
parent30646c48275b73e0bea646451fb4329ba0b6818e (diff)
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')
-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;
}