1
0
mirror of https://git.savannah.gnu.org/git/emacs.git synced 2024-11-22 07:09:54 +00:00

Always perform Eshell process cleanup runs in the Eshell buffer

Previously, some code executed in a timer, which could execute in the
wrong buffer, leading to a hang.

* lisp/eshell/esh-proc.el (eshell-sentinel): Use 'with-current-buffer'
in the timer function.

* test/lisp/eshell/esh-proc-tests.el (eshell-test-value): New variable.
(esh-proc-test/sentinel/change-buffer): New test.

(cherry picked from commit da4bc5c927)
This commit is contained in:
Jim Porter 2024-06-25 21:39:35 -07:00
parent 8b1841021c
commit 1809f6a93e
2 changed files with 40 additions and 22 deletions

View File

@ -530,28 +530,30 @@ PROC is the process that's exiting. STRING is the exit message."
(not (process-live-p proc))))
(finish-io
(lambda ()
(if (or (process-get proc :eshell-busy)
(and wait-for-stderr (car stderr-live)))
(progn
(eshell-debug-command 'process
"i/o busy for process `%s'" proc)
(run-at-time 0 nil finish-io))
(when data
(ignore-error eshell-pipe-broken
(eshell-output-object
data index handles)))
(eshell-close-handles
status
(when status (list 'quote (= status 0)))
handles)
;; Clear the handles to mark that we're 100%
;; finished with the I/O for this process.
(process-put proc :eshell-handles nil)
(eshell-debug-command 'process
"finished external process `%s'" proc)
(if primary
(run-hook-with-args 'eshell-kill-hook proc string)
(setcar stderr-live nil))))))
(with-current-buffer (process-buffer proc)
(if (or (process-get proc :eshell-busy)
(and wait-for-stderr (car stderr-live)))
(progn
(eshell-debug-command 'process
"i/o busy for process `%s'" proc)
(run-at-time 0 nil finish-io))
(when data
(ignore-error eshell-pipe-broken
(eshell-output-object
data index handles)))
(eshell-close-handles
status
(when status (list 'quote (= status 0)))
handles)
;; Clear the handles to mark that we're 100%
;; finished with the I/O for this process.
(process-put proc :eshell-handles nil)
(eshell-debug-command 'process
"finished external process `%s'" proc)
(if primary
(run-hook-with-args 'eshell-kill-hook
proc string)
(setcar stderr-live nil)))))))
(funcall finish-io)))
(when-let ((entry (assq proc eshell-process-list)))
(eshell-remove-process-entry entry))))))

View File

@ -45,6 +45,8 @@
"'")
"A shell command that prints the standard streams connected as TTYs.")
(defvar eshell-test-value nil)
;;; Tests:
@ -130,6 +132,20 @@
(should (= eshell-last-command-status 1))
(should (eq eshell-last-command-result nil)))))
(ert-deftest esh-proc-test/sentinel/change-buffer ()
"Check that changing the current buffer while running a command works.
See bug#71778."
(eshell-with-temp-buffer bufname ""
(with-temp-eshell
(let (eshell-test-value)
(eshell-insert-command
(concat (format "for i in 1 2 {sleep 1; echo hello} > #<%s>; " bufname)
"setq eshell-test-value t"))
(with-current-buffer bufname
(eshell-wait-for (lambda () eshell-test-value))
(should (equal (buffer-string) "hellohello")))
(eshell-match-command-output "echo goodbye" "\\`goodbye\n")))))
;; Pipelines