Subject: bug#56025: 29.0.50; em-extpipe-test-2 times out on EMBA and Cygwin

From: Ken Brown <[email-masked]>
Date: Wed, 6 Jul 2022 18:33:45 -0400

On 6/30/2022 11:52 PM, Jim Porter wrote:
> On 6/27/2022 2:19 PM, Ken Brown wrote:
>> On 6/27/2022 3:18 PM, Jim Porter wrote:
>>> I'd be very hesitant to do this, since as you mention above, this seems like 
>>> a timing issue, and it's entirely possible that there are other, more 
>>> widespread issues on Cygwin here. We'd also want to check the system that the 
>>> process is actually running on; otherwise, remoting into a Cygwin system (via 
>>> Tramp) would still exhibit the problem. I'll see if I can get a Cygwin 
>>> environment up to test things out in the next week-ish.
>>
>> OK, thanks.  Let me know if you need any help with that.
> 
> Ok, I've got Cygwin set up (though I'm just using the prebuilt Cygwin Emacs for 
> now). I can confirm that the following hangs until I send another EOF via `C-c 
> C-d':
> 
>    echo hi | rev

Yes, but that's because of the behavior of certain platforms (e.g., Cygwin and 
Solaris) with respect to EOF, as I said in an earlier message.  We've changed 
that for Cygwin, so that Cygwin now behaves the same as GNU/Linux, but the 
change won't take effect until Cygwin 3.4.0 is released.  In any case, that 
issue has already been fixed on the master branch.

Aside from that issue, I never had an issue with

   echo hi | rev

but only with

   echo hi | sh -c rev

I have no idea why that should be different.

> However, if I evaluate the following first, the above command works just fine:
> 
>    (add-to-list 'eshell-needs-pipe "rev")
> 
> Normally, Eshell starts each process using ptys to control them. However, the 
> above Elisp code tells Eshell to use a pipe for "rev"[1].

That makes sense.  You're no longer relying on Eshell sending EOF to rev, but 
rather you're letting rev discover EOF because no process holds the pipe open 
for writing, forcing any pending read to stop blocking.

And, for the same reason, evaluating

   (add-to-list 'eshell-needs-pipe "sh")

solves the problem with "echo hi | sh -c rev".

> I'm not totally clear 
> on all the subtleties here, but it seems to me that it would make more sense for 
> rev to use a pipe for its stdin and a pty for its stdout. That's not possible 
> with subprocesses in Emacs though (as far as I know).
> 
> However, I don't think this fully answers things, since I also see inconsistent 
> results if I run "echo hi | rev" a bunch of times. Sometimes it prints "ih" and 
> then I need to hit `C-c C-d` once to stop it. Other times it doesn't print 
> anything and I need to hit `C-c C-d' twice.

Interesting.  I've never seen that.  It's as though "rev" just didn't get one of 
the EOFs.

> There must be some kind of race 
> condition, maybe in Emacs's src/process.c?

I'll poke around, but I'm no expert on how this all works.

Ken