emacs-devel
[Top][All Lists]
Advanced

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

Re: esh-proc test failures


From: Jim Porter
Subject: Re: esh-proc test failures
Date: Tue, 23 Aug 2022 08:57:37 -0700

On 8/23/2022 4:37 AM, Eli Zaretskii wrote:
Cc: larsi@gnus.org, emacs-devel@gnu.org
From: Jim Porter <jporterbugs@gmail.com>
Date: Mon, 22 Aug 2022 20:53:47 -0700

If Eshell tries to write to a process object and it fails, it gets
treated as a broken pipe. Technically, it signals 'eshell-pipe-broken',
but that's roughly equivalent to SIGPIPE. This is mainly so that in a
pipeline like "foo | bar", if "bar" terminates, Eshell can inform "foo"
of the fact; on POSIX systems, it would send SIGPIPE, but on MS Windows,
it just calls 'delete-process'. This is important because we want to be
sure that if you have a pipeline like "yes | head", the "yes" gets
stopped once "head" is done.

So you basically assume that _any_ problem in the pipe was due to
SIGPIPE?  That could be too optimistic: it could be due to something
much more mundane and unrelated.

(Technically Eshell assumes that any error raised from 'process-send-string' should *break* the pipe.) To be more cautious, we could say that we should only break the pipe if we get an error *and* the process we're writing to has terminated. See attached.

Not sure I understand completely what you are saying here, but AFAIR
writing to a closed pipe on MS-Windows will cause EINVAL errno.

Indeed, it would be nice if we could force things so that an MS Windows
program gets EINVAL for its WriteFile call, but because Eshell only
interacts indirectly with the program's output, it's too late to do that
by the time Eshell responds.

I don't think I follow.  When the write fails, we get an error and
propagate it all the way up to the caller.

If we signal an error in a process filter, does Emacs inform the process that wrote that data of the error? My tests showed that it didn't, but maybe I was doing something wrong.

The goal here is just to tell a process that the thing it's writing to is gone, and that it should give up. This is more complex than usual because of how many steps Eshell goes through:

  some process
    ->
  'eshell-insertion-filter' process filter
    ->
  'eshell-output-object'
    ->
  'process-send-string' to another process

Then, if 'process-send-string' signals an error, we need to relay that back to the original process somehow so that it stops (or possibly does something else appropriate).

I could expand the comment to explain that this value is
somewhat-arbitrary and just designed to match GNU/Linux.

Yes, please.

How does the attached look?

Looks OK, but are you sure about the "128" part? shouldn't it be 256
instead?  And perhaps explain why you add 128 (or whatever).

I think the idea is that it's setting the high bit of an unsigned 8-bit value. I'm sure that the final number (141) is right for GNU/Linux at least:

  $ yes | head; echo ${PIPESTATUS[0]} ${PIPESTATUS[1]}
  y
  ...
  141 0

I tweaked the comment to explain this number in terms of "setting the high bit", which I hope should be clearer.

Well, it depends on what we think users would expect. Currently, I don't
think Eshell provides the necessary functionality to tell when the
process "foo" fails (i.e. returns a non-zero exit status) in the
pipeline "foo | bar".

But we can do that, right?  The information about the exit status is
available to the SIGCHLD handler or a similar interface.

Yes, we could. Nothing in process.c would have to change to support this; it's just a limitation of how Eshell is programmed. In a pipeline like "yes | head", the 'eshell-last-command-status' of "yes" would be 141, but it would then get overwritten by "head"'s status (0). Eshell would need to track those in a list or something.

Attachment: 0001-Handle-eshell-pipe-broken-when-evaluating-Lisp-forms.patch
Description: Text document


reply via email to

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