|
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 processThen, 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 0I 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.
0001-Handle-eshell-pipe-broken-when-evaluating-Lisp-forms.patch
Description: Text document
[Prev in Thread] | Current Thread | [Next in Thread] |