struct poll_kevent_copyin_args *pkap;
struct pollfd *pfd;
struct kevent kev;
+ int count_res;
int i;
u_int pi;
if (kevp[i].ident == pfd->fd) {
/*
* A single descriptor may generate an error against
- * more than one filter, make sure to set the appropriate
- * flags but do not increment (*res) more than once.
+ * more than one filter, make sure to set the
+ * appropriate flags but do not increment (*res)
+ * more than once.
*/
+ count_res = (pfd->revents == 0);
if (kevp[i].flags & EV_ERROR) {
switch(kevp[i].data) {
case EBADF:
/* Bad file descriptor */
- if (pfd->revents == 0)
+ if (count_res)
++*res;
pfd->revents |= POLLNVAL;
break;
if (kevp[i].filter != EVFILT_READ &&
kevp[i].filter != EVFILT_WRITE &&
kevp[i].data != EOPNOTSUPP) {
- if (pfd->revents == 0)
+ if (count_res == 0)
++*res;
pfd->revents |= POLLERR;
}
continue;
}
- if (kevp[i].flags & EV_EOF) {
- if (pfd->revents == 0)
- ++*res;
+ if (kevp[i].flags & EV_EOF)
pfd->revents |= POLLHUP;
- continue;
- }
switch (kevp[i].filter) {
case EVFILT_READ:
pi, pkap->nfds, pfd->fd, pfd->revents);
}
- ++*res;
- continue;
+ if (count_res && pfd->revents)
+ ++*res;
} else {
if (nseldebug) {
kprintf("poll index %d mismatch %ju/%d\n",
lwkt_gettoken(&rpipe->pipe_wlock);
kn->kn_data = rpipe->pipe_buffer.windex - rpipe->pipe_buffer.rindex;
- if (rpipe->pipe_state & PIPE_REOF) {
+
+ /*
+ * Only set EOF if all data has been exhausted
+ */
+ if ((rpipe->pipe_state & PIPE_REOF) && kn->kn_data == 0) {
kn->kn_flags |= EV_EOF;
ready = 1;
}
return (0);
}
kn->kn_data = so->so_rcv.ssb_cc;
- if (so->so_state & SS_CANTRCVMORE) {
+
+ /*
+ * Only set EOF if all data has been exhausted.
+ */
+ if ((so->so_state & SS_CANTRCVMORE) && kn->kn_data == 0) {
kn->kn_flags |= EV_EOF;
kn->kn_fflags = so->so_error;
return (1);
lwkt_gettoken(&vp->v_token);
kn->kn_data = so->so_rcv.ssb_cc;
- if (so->so_state & SS_ISDISCONNECTED) {
+ if ((so->so_state & SS_ISDISCONNECTED) && kn->kn_data == 0) {
kn->kn_flags |= EV_EOF;
lwkt_reltoken(&vp->v_token);
return (1);