Subject: Re: bug#79079: 31.0.50; Piped command output is sometimes lost in Eshell

From: Paul Eggert <[email-masked]>
Date: Sun, 27 Jul 2025 15:03:18 -0700

On 2025-07-27 12:34, Jim Porter wrote:
> If we're being technical, Eshell does use pipes for its pipe operator, 
> but there's an additional layer of indirection that makes it difficult 
> to simulate the usual POSIX shell piping:
> 
>    process A -> stdout pipe -> process filter -> process-send-string -> 
> stdin pipe -> process B
> 
> If 'process-send-string' fails, we raise a Lisp signal 'eshell-pipe- 
> broken', that tries to be as much like SIGPIPE as we can. Because of 
> this indirection though, process A won't see an EPIPE/SIGPIPE at the 
> normally-expected time

Thanks for the explanation. Is this documented? Might not hurt to do so 
if it's not documented already. Maybe that can be part of your patch 
series (and I can certainly sympathize with those patches taking time to 
get right!)

>             ;; The output pipe broke, so send SIGPIPE to the
>             ;; process.  NOTE: Due to the additional indirection
>             ;; of Emacs process filters, the process will likely
>             ;; see the SIGPIPE later than it would in a regular
>             ;; shell, which could cause problems.

Suppose we change Emacs to not send SIGPIPE to A in this situation, but 
instead to just close Emacs's end of A's output pipe. Then when A 
eventually gets around to writing to its output pipe it will get a 
SIGPIPE if it is not ignoring that signal, and an EPIPE failure 
otherwise, and this will be closer to what happens with ordinary shell 
pipes.

An objection to such a change, which is hinted at in the comment, is 
that A might get a SIGPIPE later than it would with an ordinary shell 
pipe, due to the extra buffering that Emacs supplies. But this objection 
isn't a deal breaker, as A can't know how big the kernel pipe buffer is 
or how the scheduler works, so it shouldn't rely on that precise of a 
schedule anyway.

If I understand things correctly a problem with the current code is that 
A can get a SIGPIPE too early, before it writes to its output pipe, or 
even if it never writes to its output pipe. That contradicts the POSIX 
behavior, and so is a more serious problem than A getting a SIGPIPE 
later than usual (which is what the comment is worried about).