NetBSD-Bugs archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
kern/59056: poll POLLHUP bugs
>Number: 59056
>Category: kern
>Synopsis: poll POLLHUP bugs
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: kern-bug-people
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Fri Feb 07 19:40:01 +0000 2025
>Originator: Taylor R Campbell
>Release:
>Organization:
The NotPolleD Foundation
>Environment:
>Description:
If you open a {pipe, socketpair} and close the read side (either side for socket pair), polling the write side for POLLOUT returns:
- POLLHUP|POLLOUT, for pipe;
- POLLOUT, for socketpair.
The pipe case is wrong because POLLHUP and POLLOUT are mutually exclusive in POSIX:
POLLHUP
A device has been disconnected, or a pipe or FIFO has been closed by the last process that had it open for writing. [...] This event and POLLOUT are mutually-exclusive; a stream can never be writable if a hangup has occurred.
https://pubs.opengroup.org/onlinepubs/9699919799/functions/poll.html
The socketpair is also wrong because any attempt to write to the socket triggers SIGPIPE/EPIPE, so surely POLLHUP must be set for it.
>How-To-Repeat:
#include <sys/socket.h>
#include <err.h>
#include <poll.h>
#include <signal.h>
#include <stdio.h>
#include <unistd.h>
static void
ignoresig(int signo)
{
}
int
main(void)
{
int s[2];
struct pollfd pfd;
int i, nfds;
if (signal(SIGPIPE, ignoresig) == SIG_ERR)
err(1, "signal(SIGPIPE)");
if (socketpair(AF_LOCAL, SOCK_STREAM, 0, s) == -1)
err(1, "socketpair");
// if (pipe(s) == -1)
// err(1, "pipe");
pfd = (struct pollfd){ .fd = s[1], .events = POLLOUT };
nfds = poll(&pfd, 1, 0);
if (nfds == -1)
err(1, "poll");
printf("nfds=%d\n", nfds);
printf("[%d] .fd=%d .revents=0x%x\n", 0, pfd.fd, pfd.revents);
if (close(s[0]) == -1)
err(1, "close");
pfd = (struct pollfd){ .fd = s[1], .events = POLLOUT };
nfds = poll(&pfd, 1, 0);
if (nfds == -1)
err(1, "poll");
printf("nfds=%d\n", nfds);
printf("[%d] .fd=%d .revents=0x%x\n", 0, pfd.fd, pfd.revents);
fflush(stdout);
char ch = 0;
if (write(s[1], &ch, 1) == -1)
err(1, "write");
return ferror(stdout);
}
>Fix:
Yes, please!
Home |
Main Index |
Thread Index |
Old Index