diff options
author | jilles <jilles@FreeBSD.org> | 2009-08-25 21:44:14 +0000 |
---|---|---|
committer | jilles <jilles@FreeBSD.org> | 2009-08-25 21:44:14 +0000 |
commit | 0b9c3c2f3dba778ac524d7fac5931cf44d5f97fe (patch) | |
tree | 2ccf45e2050ec4c93f8467202055c0084e85bbdc /sys/kern/uipc_socket.c | |
parent | cd97215dd65e5058b5bd29ccae52218ae46695bc (diff) | |
download | FreeBSD-src-0b9c3c2f3dba778ac524d7fac5931cf44d5f97fe.zip FreeBSD-src-0b9c3c2f3dba778ac524d7fac5931cf44d5f97fe.tar.gz |
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
Diffstat (limited to 'sys/kern/uipc_socket.c')
-rw-r--r-- | sys/kern/uipc_socket.c | 12 |
1 files changed, 7 insertions, 5 deletions
diff --git a/sys/kern/uipc_socket.c b/sys/kern/uipc_socket.c index c60b8d1..2f4dd92 100644 --- a/sys/kern/uipc_socket.c +++ b/sys/kern/uipc_socket.c @@ -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)) { |