From f2159cc7908d09fcb3e11c23a28760dc96ccfe8e Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Sun, 23 Aug 2009 12:44:15 +0000 Subject: [PATCH] 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 --- sys/kern/sys_generic.c | 7 +++++++ sys/kern/uipc_socket.c | 12 +++++------- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/sys/kern/sys_generic.c b/sys/kern/sys_generic.c index de703483b0c..bd0f2793378 100644 --- a/sys/kern/sys_generic.c +++ b/sys/kern/sys_generic.c @@ -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++; } diff --git a/sys/kern/uipc_socket.c b/sys/kern/uipc_socket.c index 2f4dd92736a..c60b8d1abce 100644 --- a/sys/kern/uipc_socket.c +++ b/sys/kern/uipc_socket.c @@ -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)) {