NetBSD Problem Report #56429

From www@netbsd.org  Fri Oct  1 11:15:19 2021
Return-Path: <www@netbsd.org>
Received: from mail.netbsd.org (mail.netbsd.org [199.233.217.200])
	(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits))
	(Client CN "mail.NetBSD.org", Issuer "mail.NetBSD.org CA" (not verified))
	by mollari.NetBSD.org (Postfix) with ESMTPS id 91BE21A921F
	for <gnats-bugs@gnats.NetBSD.org>; Fri,  1 Oct 2021 11:15:19 +0000 (UTC)
Message-Id: <20211001111517.F1D931A9239@mollari.NetBSD.org>
Date: Fri,  1 Oct 2021 11:15:17 +0000 (UTC)
From: david@netascale.com
Reply-To: david@netascale.com
To: gnats-bugs@NetBSD.org
Subject: poll(2) should yield POLLHUP when last writer to a fifo close()'s it
X-Send-Pr-Version: www-1.0

>Number:         56429
>Category:       kern
>Synopsis:       poll(2) should yield POLLHUP when last writer to a fifo close()'s it
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    thorpej
>State:          closed
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Fri Oct 01 11:20:00 +0000 2021
>Closed-Date:    Tue Oct 05 17:37:03 +0000 2021
>Last-Modified:  Tue Oct 05 17:37:03 +0000 2021
>Originator:     David Mackay
>Release:        9.2
>Organization:
>Environment:
NetBSD netbsd.fritz.box 9.2 NetBSD 9.2 (GENERIC) #0: Wed May 12 13:15:55 UTC 2021  mkrepro@mkrepro.NetBSD.org:/usr/src/sys/arch/amd64/compile/GENERIC amd64
>Description:
According to the most recent POSIX standard on poll(2):

"POLLHUP
A device has been disconnected, or a pipe or FIFO has been closed by the last process that had it open for writing.
[...]
The POLLHUP event does not occur for FIFOs just because the FIFO is not open for writing. It only occurs when the FIFO is closed by the last writer and persists until some process opens the FIFO for writing or until all read-only file descriptors for the FIFO are closed."

This, however, is not what happens on NetBSD. Attached below is a test case which should print something like:

poll() = 1, revents: POLLIN 0, POLLERR 0, POLLHUP 16, POLLNVAL 0

then exit. This behaviour is observed on GNU/Linux. (On OpenBSD and FreeBSD, POLLIN is also set.) However, on NetBSD, this happens:

poll() = 1, revents: POLLIN 1, POLLERR 0, POLLHUP 0, POLLNVAL 0
read() = 0

and the test case continues waiting.

Note: kevent() with EVFILT_READ *does* return EV_EOF in this case.
>How-To-Repeat:
#include <sys/types.h>
#include <sys/stat.h>

#include <err.h>
#include <fcntl.h>
#include <poll.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int
main()
{
	struct pollfd pfd;
	char buf[255];
	int wfd;

	unlink("fifo");

	if (mkfifo("fifo", 0600))
		err(EXIT_FAILURE, "mkfifo");

	pfd.fd = open("fifo", O_RDONLY | O_NONBLOCK);
	if (pfd.fd < 0)
		err(EXIT_FAILURE, "open for read");

	wfd = open("fifo", O_WRONLY);
	if (wfd < 0)
		err(EXIT_FAILURE, "open for write");

	/* close to generate a POLLHUP */
	close(wfd);

	pfd.events = POLLIN;

	do {
		int r = poll(&pfd, 1, -1);

		printf("poll() = %d, revents: POLLIN %d, POLLERR %d, "
		       "POLLHUP %d, POLLNVAL %d\n",
			r, pfd.revents & POLLIN, pfd.revents & POLLERR,
			pfd.revents & POLLHUP, pfd.revents & POLLNVAL);

		if (pfd.revents & POLLIN) {
			r = read(pfd.fd, buf, sizeof buf);
			printf("read() = %d\n", r);
		}
	} while (!(pfd.revents & (POLLERR | POLLHUP | POLLNVAL)));

	return 0;
}

>Fix:
A POLLHUP revent ought to be yielded.

>Release-Note:

>Audit-Trail:

Responsible-Changed-From-To: kern-bug-people->thorpej
Responsible-Changed-By: thorpej@NetBSD.org
Responsible-Changed-When: Fri, 01 Oct 2021 16:13:47 +0000
Responsible-Changed-Why:
I've been doing some work in this area recently, so I'll grab this one.


From: "Jason R Thorpe" <thorpej@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc: 
Subject: PR/56429 CVS commit: src
Date: Sat, 2 Oct 2021 02:07:42 +0000

 Module Name:	src
 Committed By:	thorpej
 Date:		Sat Oct  2 02:07:42 UTC 2021

 Modified Files:
 	src/sys/kern: uipc_socket2.c
 	src/sys/miscfs/fifofs: fifo_vnops.c
 	src/tests/lib/libc/sys: t_poll.c

 Log Message:
 - fifo_poll(): If the last writer has disappeared, detect this and return
   POLLHUP, per POSIX.
 - fifo_close(): Use the new fifo_socantrcvmore(), which is like the
   garden-variety socantrcvmore(), except it specifies POLL_HUP rather
   than POLL_IN (so the correct code for SIGIO is sent).
 - sowakeup(): Allow POLL_HUP as a code (notifies poll'ers with POLLHUP).
 - Add test cases for correct POLLHUP behavior with FIFOs.

 Fixes PR kern/56429.


 To generate a diff of this commit:
 cvs rdiff -u -r1.139 -r1.140 src/sys/kern/uipc_socket2.c
 cvs rdiff -u -r1.86 -r1.87 src/sys/miscfs/fifofs/fifo_vnops.c
 cvs rdiff -u -r1.4 -r1.5 src/tests/lib/libc/sys/t_poll.c

 Please note that diffs are not public domain; they are subject to the
 copyright notices on the relevant files.

State-Changed-From-To: open->needs-pullups
State-Changed-By: thorpej@NetBSD.org
State-Changed-When: Sat, 02 Oct 2021 02:17:51 +0000
State-Changed-Why:
Issue resolved, pullup requested.


From: "Martin Husemann" <martin@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc: 
Subject: PR/56429 CVS commit: [netbsd-9] src
Date: Sat, 2 Oct 2021 11:07:56 +0000

 Module Name:	src
 Committed By:	martin
 Date:		Sat Oct  2 11:07:56 UTC 2021

 Modified Files:
 	src/sys/kern [netbsd-9]: uipc_socket2.c
 	src/sys/miscfs/fifofs [netbsd-9]: fifo_vnops.c
 	src/tests/lib/libc/sys [netbsd-9]: t_poll.c

 Log Message:
 Pull up following revision(s) (requested by thorpej in ticket #1350):

 	sys/kern/uipc_socket2.c: revision 1.140
 	tests/lib/libc/sys/t_poll.c: revision 1.5
 	sys/miscfs/fifofs/fifo_vnops.c: revision 1.87

 - fifo_poll(): If the last writer has disappeared, detect this and return
   POLLHUP, per POSIX.
 - fifo_close(): Use the new fifo_socantrcvmore(), which is like the
   garden-variety socantrcvmore(), except it specifies POLL_HUP rather
   than POLL_IN (so the correct code for SIGIO is sent).
 - sowakeup(): Allow POLL_HUP as a code (notifies poll'ers with POLLHUP).
 - Add test cases for correct POLLHUP behavior with FIFOs.

 Fixes PR kern/56429.


 To generate a diff of this commit:
 cvs rdiff -u -r1.134.2.1 -r1.134.2.2 src/sys/kern/uipc_socket2.c
 cvs rdiff -u -r1.79 -r1.79.8.1 src/sys/miscfs/fifofs/fifo_vnops.c
 cvs rdiff -u -r1.3 -r1.3.34.1 src/tests/lib/libc/sys/t_poll.c

 Please note that diffs are not public domain; they are subject to the
 copyright notices on the relevant files.

State-Changed-From-To: needs-pullups->feedback
State-Changed-By: thorpej@NetBSD.org
State-Changed-When: Sat, 02 Oct 2021 13:53:07 +0000
State-Changed-Why:
Fix has been pulled up into the netbsd-9 branch.  Can you confirm that
the patch fixes your application's issue?


From: David MacKay <david@netascale.com>
To: gnats-bugs@netbsd.org
Cc: "thorpej@netbsd.org" <thorpej@netbsd.org>,
	"gnats-admin@netbsd.org" <gnats-admin@netbsd.org>,
	"netbsd-bugs@netbsd.org" <netbsd-bugs@netbsd.org>
Subject: Re: kern/56429 (poll(2) should yield POLLHUP when last writer to a
 fifo close()'s it)
Date: Tue, 5 Oct 2021 12:28:20 -0400 (EDT)

 Good evening,

 This has fixed the issue - thanks for such a quick response!

 Kind regards,
 David MacKay

 > On 10/02/2021 9:53 AM thorpej@netbsd.org wrote:
 > 
 >  
 > Synopsis: poll(2) should yield POLLHUP when last writer to a fifo close()'s it
 > 
 > State-Changed-From-To: needs-pullups->feedback
 > State-Changed-By: thorpej@NetBSD.org
 > State-Changed-When: Sat, 02 Oct 2021 13:53:07 +0000
 > State-Changed-Why:
 > Fix has been pulled up into the netbsd-9 branch.  Can you confirm that
 > the patch fixes your application's issue?

State-Changed-From-To: feedback->closed
State-Changed-By: thorpej@NetBSD.org
State-Changed-When: Tue, 05 Oct 2021 17:37:03 +0000
State-Changed-Why:
Originator confirms issue is resolved.


>Unformatted:

NetBSD Home
NetBSD PR Database Search

(Contact us) $NetBSD: query-full-pr,v 1.46 2020/01/03 16:35:01 leot Exp $
$NetBSD: gnats_config.sh,v 1.9 2014/08/02 14:16:04 spz Exp $
Copyright © 1994-2020 The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.