|
From: | Jim Porter |
Subject: | Re: esh-proc test failures |
Date: | Mon, 22 Aug 2022 20:53:47 -0700 |
On 8/22/2022 7:27 PM, Eli Zaretskii wrote:
Cc: larsi@gnus.org, emacs-devel@gnu.org From: Jim Porter <jporterbugs@gmail.com> Date: Mon, 22 Aug 2022 12:23:37 -0700+ (eshell-pipe-broken + ;; 141 is 128 + 13 (the numeric value of SIGPIPE). + (setq eshell-last-command-status 141) + nil)This is non-portable, I think on two counts: . the assumption that the exit code is the signal number left-shifted by N bits (btw, isn't N = 8, not 7?) . the assumption that SIGPIPE is signal 13 (does Posix mandate that?) What do we expect to happen here on MS-Windows and other non-Posix platforms, where both of the above assumptions are false?The only thing that really needs to happen here is that the signal is caught so it doesn't bubble up past this point and break things.How do you accomplish that? On MS-Windows there's no SIGPIPE signal, for example.
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.
Eshell's implementation isn't perfect though; since Emacs uses process filters, Eshell actually sends the SIGPIPE later than otherwise expected. Still, it's probably better than hanging indefinitely. (Fixing this "properly" would probably require dramatically reworking how Emacs interacts with subprocesses, which I think would be too risky to do, since we don't want to break things in process.c.)
For the actual code that raises this signal, see the end of the function 'eshell-output-object-to-target' in lisp/eshell/esh-io.el.
The command status could be anything really, and I'm pretty sure Eshell doesn't even allow inspecting this value (yet), since it would only occur for a non-last item in a pipeline. (In the future, Eshell could offer something like $PIPESTATUS to examine this.)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 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?
Alternately, if there's a way to inspect the system's conventions to use here (e.g. getting the numeric value of SIGPIPE for the current system), we could do that too.I might be able to help if I understand better what is needed here.
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".
However, if it did, I think the most a user would care about is that there's some consistent way of telling what went wrong. If there were a way to determine what convention the current system uses to say "foo terminated because it tried to write to bar after bar exited", we could use that.
I'm not sure this part is worth spending a lot of time on though, especially since the exit status of "foo" isn't currently accessible as far as I know.
0001-Handle-eshell-pipe-broken-when-evaluating-Lisp-forms.patch
Description: Text document
[Prev in Thread] | Current Thread | [Next in Thread] |