Fix poll() on half-closed sockets, while retaining POLLHUP for fifos.

This reverts part of r196460, so that sockets only return POLLHUP if both
directions are closed/error. Fifos get POLLHUP by closing the unused
direction immediately after creating the sockets.

The tools/regression/poll/*poll.c tests now pass except for two other things:
- if POLLHUP is returned, POLLIN is always returned as well instead of only
  when there is data left in the buffer to be read
- fifo old/new reader distinction does not work the way POSIX specs it

Reviewed by:	kib, bde
This commit is contained in:
Jilles Tjoelker 2009-08-25 21:44:14 +00:00
parent 986dffaf53
commit 74d1c4927a
2 changed files with 10 additions and 5 deletions

View File

@ -193,6 +193,9 @@ fifo_open(ap)
goto fail2;
fip->fi_writesock = wso;
error = soconnect2(wso, rso);
/* Close the direction we do not use, so we can get POLLHUP. */
if (error == 0)
error = soshutdown(rso, SHUT_WR);
if (error) {
(void)soclose(wso);
fail2:

View File

@ -2898,11 +2898,13 @@ 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 |= POLLHUP;
if (so->so_snd.sb_state & SBS_CANTSENDMORE)
revents |= POLLHUP;
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 (revents == 0) {
if (events & (POLLIN | POLLPRI | POLLRDNORM | POLLRDBAND)) {