coreutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH] tee: Add --pipe-check to allow instantly detecting closed ou


From: Carl Edquist
Subject: Re: [PATCH] tee: Add --pipe-check to allow instantly detecting closed outputs
Date: Sat, 10 Dec 2022 08:40:43 -0600 (CST)

On Fri, 9 Dec 2022, Carl Edquist wrote:

On Fri, 9 Dec 2022, Arsen Arsenović wrote:

Originally i had imagined (or hoped) that this broken-pipe detection could also be used for sockets (that was how the issue came up for me), but it seems the semantics for sockets are different than for pipes.

This might require POLLPRI or POLLRDHUP or such. Can you try with those to the set of events in pollfd?

Oh interesting! I had assumed these wouldn't help - POLLPRI is for OOB data, and, I had assumed POLLRDHUP was only for polling the read side of a socket (thus POLL*RD*HUP), to determine if the remote write end was shutdown. But you are right, poll() returns with POLLRDHUP in revents as soon as the remote end is closed. Thanks for the tip!

I assume the reason this works is, even though i have in mind that i am monitoring the socket as an output, the socket serves as an input also (it's open for RW). So, if my interpretation is correct, POLLRDHUP is actually monitoring the local read side of the socket. And so, poll() is actually detecting the remote write side getting shutdown.

This is not technically the same thing as monitoring the local output side, but if the remote end of the socket closes entirely (shutting down the remote read and write ends together), then that tells us about the local output side as well.

This definitely seems to work for the case i was playing with, though i'm not sure if it would behave as intended if the remote side only shut down its read or write end (but not both).

Alright, i got a chance to play around with this more locally with socketpairs. Unfortunately, i've confirmed that POLLRDHUP is clearly intended for monitoring the local read end of a socket, not the local write end. (Thus it is not what we want for monitoring an output.)

In each case below, i started with a socket open for RW on both ends, and poll()ed the local socket fd with POLLRDHUP. I observed the following:

- shutdown local read -> POLLRDHUP
- shutdown local write -> nothing detected
- shutdown remote read -> nothing detected
- shutdown remote write -> POLLRDHUP

This is exactly the reverse of what we want when monitoring a socket as an output. Shutting down the local read end should be fine (since we are using it for output). Shutting down the local write end should be considered like a broken pipe, since nothing further can be sent. Shutting down the remote read end should also be considered like a broken pipe, as with a normal pipe. Shutting down the remote write end should be fine, since supposedly the local end of the socket is used for output.

Again, the reason POLLRDHUP worked in my case is that the remote end closed completely (shutting down remote read and write). But for cases where either end (local or remote) shuts down only read or write, using POLLRDHUP checks for exactly the wrong thing.

It seems that there ought to be a "POLLWRHUP", but as far as i can tell that does not exist.

...

My conclusion (as far as i can tell) is that we can't do this iopoll jazz correctly for sockets.

The up side though is that that makes it ok to explicitly check that the output is a pipe, and then only worry about pipe semantics. Which makes the select-based implementation safe, since pipe fds are not open for RW.

Carl


reply via email to

[Prev in Thread] Current Thread [Next in Thread]