From: millert Date: Sun, 10 May 2015 22:35:38 +0000 (+0000) Subject: Set POLLHUP even if no valid events were specified as per POSIX. X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=b7b44fe5796e416f560eb15867dc757db11a47d6;p=openbsd Set POLLHUP even if no valid events were specified as per POSIX. Since we use the poll backend for select(2), care must be taken not to set the fd's bit in writefds in this case. A kernel-only flag, POLLNOHUP, is used by selscan() to tell the poll backend not to return POLLHUP on EOF. This is currently only used by fifo_poll(). The fifofs regress now passes. OK guenther@ --- diff --git a/sys/kern/sys_generic.c b/sys/kern/sys_generic.c index 57b1813f080..cefcf9f7a5f 100644 --- a/sys/kern/sys_generic.c +++ b/sys/kern/sys_generic.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sys_generic.c,v 1.97 2015/04/30 09:20:51 mpi Exp $ */ +/* $OpenBSD: sys_generic.c,v 1.98 2015/05/10 22:35:38 millert Exp $ */ /* $NetBSD: sys_generic.c,v 1.24 1996/03/29 00:25:32 cgd Exp $ */ /* @@ -712,7 +712,7 @@ selscan(struct proc *p, fd_set *ibits, fd_set *obits, int nfd, int ni, fd_mask bits; struct file *fp; int n = 0; - static const int flag[3] = { POLLIN, POLLOUT, POLLPRI }; + static const int flag[3] = { POLLIN, POLLOUT|POLLNOHUP, POLLPRI }; for (msk = 0; msk < 3; msk++) { fd_set *pibits = (fd_set *)&cibits[msk*ni]; @@ -940,8 +940,10 @@ doppoll(struct proc *p, struct pollfd *fds, u_int nfds, if ((error = copyin(fds, pl, sz)) != 0) goto bad; - for (i = 0; i < nfds; i++) + for (i = 0; i < nfds; i++) { + pl[i].events &= ~POLLNOHUP; pl[i].revents = 0; + } if (tsp != NULL) { getnanouptime(&rts); diff --git a/sys/miscfs/fifofs/fifo_vnops.c b/sys/miscfs/fifofs/fifo_vnops.c index 41a6f8ad2f9..4d6a0d7b9f3 100644 --- a/sys/miscfs/fifofs/fifo_vnops.c +++ b/sys/miscfs/fifofs/fifo_vnops.c @@ -1,4 +1,4 @@ -/* $OpenBSD: fifo_vnops.c,v 1.46 2015/05/05 20:14:10 millert Exp $ */ +/* $OpenBSD: fifo_vnops.c,v 1.47 2015/05/10 22:35:39 millert Exp $ */ /* $NetBSD: fifo_vnops.c,v 1.18 1996/03/16 23:52:42 christos Exp $ */ /* @@ -296,28 +296,28 @@ fifo_poll(void *v) int revents = 0; /* - * Just return if there are no supported events specified, * FIFOs don't support out-of-band or high priority data. */ if (ap->a_fflag & FREAD) events |= ap->a_events & (POLLIN | POLLRDNORM); if (ap->a_fflag & FWRITE) events |= ap->a_events & (POLLOUT | POLLWRNORM); - if (events == 0) - return (0); if (events & (POLLIN | POLLRDNORM)) { if (soreadable(rso)) revents |= events & (POLLIN | POLLRDNORM); } /* NOTE: POLLHUP and POLLOUT/POLLWRNORM are mutually exclusive */ - if (rso->so_state & SS_ISDISCONNECTED) { + if ((rso->so_state & SS_ISDISCONNECTED) && !(ap->a_events & POLLNOHUP)) { revents |= POLLHUP; } else if (events & (POLLOUT | POLLWRNORM)) { if (sowriteable(wso)) revents |= events & (POLLOUT | POLLWRNORM); } if (revents == 0) { + /* We want to return POLLHUP even if no valid events set. */ + if (events == 0 && !(ap->a_events & POLLNOHUP)) + events = POLLIN; if (events & (POLLIN | POLLRDNORM)) { selrecord(ap->a_p, &rso->so_rcv.sb_sel); rso->so_rcv.sb_flagsintr |= SB_SEL; diff --git a/sys/sys/poll.h b/sys/sys/poll.h index 89d77d31a89..8667b993672 100644 --- a/sys/sys/poll.h +++ b/sys/sys/poll.h @@ -1,4 +1,4 @@ -/* $OpenBSD: poll.h,v 1.13 2013/04/29 18:35:07 guenther Exp $ */ +/* $OpenBSD: poll.h,v 1.14 2015/05/10 22:35:38 millert Exp $ */ /* * Copyright (c) 1996 Theo de Raadt @@ -47,6 +47,9 @@ typedef unsigned int nfds_t; #define POLLWRNORM POLLOUT #define POLLRDBAND 0x0080 #define POLLWRBAND 0x0100 +#ifdef _KERNEL +#define POLLNOHUP 0x1000 /* internal use only */ +#endif #define INFTIM (-1)