kernel - Make returned pollfd's more conformant with legacy poll
authorSamuel J. Greear <sjg@thesjg.com>
Tue, 29 Jun 2010 23:47:53 +0000 (23:47 +0000)
committerSamuel J. Greear <sjg@thesjg.com>
Wed, 30 Jun 2010 00:35:40 +0000 (00:35 +0000)
* Do not set ready states in revents if an error condition is present

* Mask out file descriptors with a descriptor id equalling -1

sys/kern/sys_generic.c

index a764f26..a05f24f 100644 (file)
@@ -1172,6 +1172,12 @@ poll_copyin(void *arg, struct kevent *kevp, int maxevents, int *events)
                /* Clear return events */
                pfd->revents = 0;
 
+               /* Do not check if fd is equal to -1 */
+               if (pfd->fd == -1) {
+                       ++pkap->pfds;
+                       continue;
+               }
+
                kev_count = 0;
                if (pfd->events & (POLLIN | POLLRDNORM))
                        kev_count++;
@@ -1215,6 +1221,23 @@ poll_copyout(void *arg, struct kevent *kevp, int count, int *res)
                if ((int)kevp[i].udata < pkap->nfds) {
                        pfd = &pkap->fds[(int)kevp[i].udata];
                        if (kevp[i].ident == pfd->fd) {
+                               if (kevp[i].flags & EV_ERROR) {
+                                       /* Bad file descriptor */
+                                       if (kevp[i].data == EBADF)
+                                               pfd->revents |= POLLNVAL;
+                                       else
+                                               pfd->revents |= POLLERR;
+
+                                       ++*res;
+                                       continue;
+                               }
+
+                               if (kevp[i].flags & EV_EOF) {
+                                       pfd->revents |= POLLHUP;
+                                       ++*res;
+                                       continue;
+                               }
+
                                switch (kevp[i].filter) {
                                case EVFILT_READ:
                                        pfd->revents |= (POLLIN | POLLRDNORM);
@@ -1227,19 +1250,7 @@ poll_copyout(void *arg, struct kevent *kevp, int count, int *res)
                                        break;
                                }
 
-                               if (kevp[i].flags & EV_ERROR) {
-                                       /* Bad file descriptor */
-                                       if (kevp[i].data == EBADF)
-                                               pfd->revents |= POLLNVAL;
-                                       else
-                                               pfd->revents |= POLLERR;
-                               }
-
-                               if (kevp[i].flags & EV_EOF)
-                                       pfd->revents |= POLLHUP;
-
                                ++*res;
-
                                continue;
                        }
                }