aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJim Porter2023-09-06 17:01:06 -0700
committerJim Porter2023-09-10 10:38:25 -0700
commit2ec41c174f988ddece12a71ddd6e414850fae2ae (patch)
treeaa435ab90ba6b84eb8ca40514bfd29e8b803e48f
parente554ee0b5f77a3b6fe70e7a4d3d60bf319879aca (diff)
downloademacs-2ec41c174f988ddece12a71ddd6e414850fae2ae.tar.gz
emacs-2ec41c174f988ddece12a71ddd6e414850fae2ae.zip
Wait for all processes in a pipeline before resuming an Eshell command
Previously, we only waited until the tail process was finished, but now, we wait for all of them. This is more consistent with other shells, and prevents some cases of a process's output coming *after* we continued past its pipeline. * lisp/eshell/esh-cmd.el (eshell-resume-command): Simplify conditionals, and check that all the foreground processes are dead before resuming Eshell command. * test/lisp/eshell/esh-cmd-tests.el (esh-cmd-test/pipeline-wait/multi-proc): New test.
-rw-r--r--lisp/eshell/esh-cmd.el18
-rw-r--r--test/lisp/eshell/esh-cmd-tests.el10
2 files changed, 21 insertions, 7 deletions
diff --git a/lisp/eshell/esh-cmd.el b/lisp/eshell/esh-cmd.el
index a67b8abcc67..ca608e0e881 100644
--- a/lisp/eshell/esh-cmd.el
+++ b/lisp/eshell/esh-cmd.el
@@ -994,13 +994,17 @@ process(es) in a cons cell like:
994 result))) 994 result)))
995 995
996(defun eshell-resume-command (proc status) 996(defun eshell-resume-command (proc status)
997 "Resume the current command when a process ends." 997 "Resume the current command when a pipeline ends."
998 (when proc 998 (when (and proc
999 (unless (or (not (stringp status)) 999 ;; Make sure STATUS is something we want to handle.
1000 (string= "stopped" status) 1000 (stringp status)
1001 (string-match eshell-reset-signals status)) 1001 (not (string= "stopped" status))
1002 (if (eq proc (eshell-tail-process)) 1002 (not (string-match eshell-reset-signals status))
1003 (eshell-resume-eval))))) 1003 ;; Make sure PROC is one of our foreground processes and
1004 ;; that all of those processes are now dead.
1005 (member proc eshell-last-async-procs)
1006 (not (seq-some #'process-live-p eshell-last-async-procs)))
1007 (eshell-resume-eval)))
1004 1008
1005(defun eshell-resume-eval () 1009(defun eshell-resume-eval ()
1006 "Destructively evaluate a form which may need to be deferred." 1010 "Destructively evaluate a form which may need to be deferred."
diff --git a/test/lisp/eshell/esh-cmd-tests.el b/test/lisp/eshell/esh-cmd-tests.el
index 3967910a53d..d625b8a6a5d 100644
--- a/test/lisp/eshell/esh-cmd-tests.el
+++ b/test/lisp/eshell/esh-cmd-tests.el
@@ -154,6 +154,16 @@ bug#59469."
154 (eshell-match-command-output "*echo hi | echo bye" 154 (eshell-match-command-output "*echo hi | echo bye"
155 "bye\nhi\n"))) 155 "bye\nhi\n")))
156 156
157(ert-deftest esh-cmd-test/pipeline-wait/multi-proc ()
158 "Check that a pipeline waits for all its processes before returning."
159 (skip-unless (and (executable-find "echo")
160 (executable-find "sh")
161 (executable-find "rev")))
162 (with-temp-eshell
163 (eshell-match-command-output
164 "*echo hello | sh -c 'sleep 1; rev' 1>&2 | *echo goodbye"
165 "goodbye\nolleh\n")))
166
157(ert-deftest esh-cmd-test/pipeline-wait/subcommand () 167(ert-deftest esh-cmd-test/pipeline-wait/subcommand ()
158 "Check that piping with an asynchronous subcommand waits for the subcommand." 168 "Check that piping with an asynchronous subcommand waits for the subcommand."
159 (skip-unless (and (executable-find "echo") 169 (skip-unless (and (executable-find "echo")