Handle 'eshell-pipe-broken' when evaluating Lisp forms in Eshell

* lisp/eshell/esh-cmd.el (eshell-exec-lisp): Handle
'eshell-pipe-broken'.

* lisp/eshell/esh-io.el (eshell-output-object-to-target): Only signal
'eshell-pipe-broken' if the process being written to has finished.

* test/lisp/eshell/esh-proc-tests.el
(esh-proc-test/pipeline-connection-type/middle)
(esh-proc-test/pipeline-connection-type/last): Remove ':unstable'.

Ref: https://lists.gnu.org/archive/html/emacs-devel/2022-08/msg00524.html
This commit is contained in:
Jim Porter 2022-08-22 09:53:24 -07:00
parent 9f692bcd84
commit f9250c5ebc
3 changed files with 18 additions and 7 deletions

View file

@ -1347,6 +1347,15 @@ case."
(apply func-or-form args)))))
(and result (funcall printer result))
result)
(eshell-pipe-broken
;; If FUNC-OR-FORM tried and failed to write some output to a
;; process, it will raise an `eshell-pipe-broken' signal (this is
;; analogous to SIGPIPE on POSIX systems). In this case, set the
;; command status to some non-zero value to indicate an error; to
;; match GNU/Linux, we use 141, which the numeric value of
;; SIGPIPE on GNU/Linux (13) with the high bit (2^7) set.
(setq eshell-last-command-status 141)
nil)
(error
(setq eshell-last-command-status 1)
(let ((msg (error-message-string err)))

View file

@ -498,10 +498,16 @@ Returns what was actually sent, or nil if nothing was sent."
((eshell-processp target)
(unless (stringp object)
(setq object (eshell-stringify object)))
(condition-case nil
(condition-case err
(process-send-string target object)
;; If `process-send-string' raises an error, treat it as a broken pipe.
(error (signal 'eshell-pipe-broken (list target)))))
(error
;; If `process-send-string' raises an error and the process has
;; finished, treat it as a broken pipe. Otherwise, just
;; re-throw the signal.
(if (memq (process-status target)
'(run stop open closed))
(signal (car err) (cdr err))
(signal 'eshell-pipe-broken (list target))))))
((consp target)
(apply (car target) object (cdr target))))

View file

@ -74,8 +74,6 @@
(ert-deftest esh-proc-test/pipeline-connection-type/middle ()
"Test that all streams are pipes when a command is in the middle of a
pipeline."
;; Repeated unreproducible errors.
:tags '(:unstable)
(skip-unless (and (executable-find "sh")
(executable-find "cat")))
(eshell-command-result-equal
@ -84,8 +82,6 @@ pipeline."
(ert-deftest esh-proc-test/pipeline-connection-type/last ()
"Test that only output streams are PTYs when a command ends a pipeline."
;; Repeated unreproducible errors.
:tags '(:unstable)
(skip-unless (executable-find "sh"))
(eshell-command-result-equal
(concat "echo | " esh-proc-test--detect-pty-cmd)