]> git.eshelyaron.com Git - emacs.git/commitdiff
Fix a race condition when evaluating Eshell commands
authorJim Porter <jporterbugs@gmail.com>
Sat, 25 May 2024 20:46:24 +0000 (13:46 -0700)
committerEshel Yaron <me@eshelyaron.com>
Sun, 26 May 2024 05:57:56 +0000 (07:57 +0200)
* lisp/eshell/esh-cmd.el (eshell-do-eval): Don't defer when all the
processes are done.

* test/lisp/eshell/esh-cmd-tests.el
(esh-cmd-test/pipeline-wait/nested-pipes): New test.

(cherry picked from commit 57dc1ed665d72bc58befa4853fa479b770fe4fcc)

lisp/eshell/esh-cmd.el
test/lisp/eshell/esh-cmd-tests.el

index dae1a77552fe82a6906da83b2a7a25f819ed78a5..57aeff592660080d6a313a6a326148fb2f51a39d 100644 (file)
@@ -1287,13 +1287,15 @@ have been replaced by constants."
                    (setcdr form (cdr new-form)))
                  (eshell-do-eval form synchronous-p))
               (if-let (((memq (car form) eshell-deferrable-commands))
-                       (procs (eshell-make-process-list result)))
+                       (procs (eshell-make-process-list result))
+                       (active (seq-some #'eshell-process-active-p procs)))
                   (if synchronous-p
                      (apply #'eshell/wait procs)
                    (eshell-manipulate form "inserting ignore form"
                      (setcar form 'ignore)
                      (setcdr form nil))
-                   (throw 'eshell-defer procs))
+                    (when active
+                      (throw 'eshell-defer procs)))
                 (list 'quote result))))))))))))
 
 ;; command invocation
index ef965a896c118c39fc020dbebb938cd27e595352..d84f8802bdc3bf04e2754b4015928bd28115f2f1 100644 (file)
@@ -213,6 +213,18 @@ This should also wait for the subcommand."
    (eshell-match-command-output "echo ${*echo hi | *cat} | *cat"
                                 "hi")))
 
+(ert-deftest esh-cmd-test/pipeline-wait/nested-pipes ()
+  "Check that piping a subcommand with its own pipe works.
+This should also wait for the subcommand."
+  (skip-unless (and (executable-find "echo")
+                    (executable-find "cat")
+                    (executable-find "sh")
+                    (executable-find "sleep")))
+  (with-temp-eshell
+    (eshell-match-command-output
+     "{ sh -c 'sleep 1; echo goodbye 1>&2' | *echo hello } | *cat"
+     "hello\ngoodbye\n")))
+
 (ert-deftest esh-cmd-test/reset-in-pipeline/subcommand ()
   "Check that subcommands reset `eshell-in-pipeline-p'."
   (skip-unless (executable-find "cat"))