svn commit: r367352 - head/sys/kern

Mateusz Guzik mjg at FreeBSD.org
Wed Nov 4 23:11:55 UTC 2020


Author: mjg
Date: Wed Nov  4 23:11:54 2020
New Revision: 367352
URL: https://svnweb.freebsd.org/changeset/base/367352

Log:
  pipe: fix POLLHUP handling if no events were specified
  
  Linux allows polling without any events specified and it happens to be the case
  in FreeBSD as well. POLLHUP has to be delivered regardless of the event mask
  and this works fine if the condition is already present. However, if it is
  missing, selrecord is only called if the eventmask has relevant bits set. This
  in particular leads to a conditon where pipe_poll can return 0 events and
  neglect to selrecord, while kern_poll takes it as an indication it has to go to
  sleep, but then there is nobody to wake it up.
  
  While the problem seems systemic to *_poll handlers the least we can do is fix
  it up for pipes.
  
  Reported by:	Jeremie Galarneau <jeremie.galarneau at efficios.com>
  Reviewed by:	kib
  Differential Revision:	https://reviews.freebsd.org/D27094

Modified:
  head/sys/kern/sys_pipe.c

Modified: head/sys/kern/sys_pipe.c
==============================================================================
--- head/sys/kern/sys_pipe.c	Wed Nov  4 22:41:54 2020	(r367351)
+++ head/sys/kern/sys_pipe.c	Wed Nov  4 23:11:54 2020	(r367352)
@@ -1458,13 +1458,17 @@ pipe_poll(struct file *fp, int events, struct ucred *a
 	}
 
 	if (revents == 0) {
-		if (fp->f_flag & FREAD && events & (POLLIN | POLLRDNORM)) {
+		/*
+		 * Add ourselves regardless of eventmask as we have to return
+		 * POLLHUP even if it was not asked for.
+		 */
+		if ((fp->f_flag & FREAD) != 0) {
 			selrecord(td, &rpipe->pipe_sel);
 			if (SEL_WAITING(&rpipe->pipe_sel))
 				rpipe->pipe_state |= PIPE_SEL;
 		}
 
-		if (fp->f_flag & FWRITE && events & (POLLOUT | POLLWRNORM)) {
+		if ((fp->f_flag & FWRITE)!= 0) {
 			selrecord(td, &wpipe->pipe_sel);
 			if (SEL_WAITING(&wpipe->pipe_sel))
 				wpipe->pipe_state |= PIPE_SEL;


More information about the svn-src-all mailing list