Fix the conformance of poll(2) for sockets after r195423 by

returning POLLHUP instead of POLLIN for several cases. Now, the
tools/regression/poll results for FreeBSD are closer to that of the
Solaris and Linux.

Also, improve the POSIX conformance by explicitely clearing POLLOUT
when POLLHUP is reported in pollscan(), making the fix global.

Submitted by:	bde
Reviewed by:	rwatson
MFC after:	1 week
This commit is contained in:
Konstantin Belousov 2009-08-23 12:44:15 +00:00
parent 69eb6d71d0
commit f2159cc790
2 changed files with 12 additions and 7 deletions

View file

@ -1228,6 +1228,13 @@ pollscan(td, fds, nfd)
selfdalloc(td, fds);
fds->revents = fo_poll(fp, fds->events,
td->td_ucred, td);
/*
* POSIX requires POLLOUT to be never
* set simultaneously with POLLHUP.
*/
if ((fds->revents & POLLHUP) != 0)
fds->revents &= ~POLLOUT;
if (fds->revents != 0)
n++;
}

View file

@ -2898,13 +2898,11 @@ sopoll_generic(struct socket *so, int events, struct ucred *active_cred,
if (so->so_oobmark || (so->so_rcv.sb_state & SBS_RCVATMARK))
revents |= events & (POLLPRI | POLLRDBAND);
if ((events & POLLINIGNEOF) == 0) {
if (so->so_rcv.sb_state & SBS_CANTRCVMORE) {
revents |= events & (POLLIN | POLLRDNORM);
if (so->so_snd.sb_state & SBS_CANTSENDMORE)
revents |= POLLHUP;
}
}
if ((events & POLLINIGNEOF) == 0)
if (so->so_rcv.sb_state & SBS_CANTRCVMORE)
revents |= POLLHUP;
if (so->so_snd.sb_state & SBS_CANTSENDMORE)
revents |= POLLHUP;
if (revents == 0) {
if (events & (POLLIN | POLLPRI | POLLRDNORM | POLLRDBAND)) {