aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJim Porter2023-09-11 22:05:38 -0700
committerJim Porter2023-09-12 11:44:27 -0700
commitfad91b56d13e7bc902cce522671ebf47b0632d45 (patch)
treec4ac8e4ddcf633c21254f349edfc515c4ec034e1
parenta0c8b458209b127834af7a70be6024bf65ae06b7 (diff)
downloademacs-fad91b56d13e7bc902cce522671ebf47b0632d45.tar.gz
emacs-fad91b56d13e7bc902cce522671ebf47b0632d45.zip
Ensure that Eshell doesn't consider a process complete until stderr is done
This will hopefully help resolve some timing issues with subprocesses in Eshell. There's now much less chance of output going missing when using redirects. * lisp/eshell/esh-proc.el (eshell-gather-process-output): Set ':eshell-stderr-live'... (eshell-sentinel): ... use it.
-rw-r--r--lisp/eshell/esh-proc.el31
1 files changed, 22 insertions, 9 deletions
diff --git a/lisp/eshell/esh-proc.el b/lisp/eshell/esh-proc.el
index f5fd982b1a4..5bfcbd6dc15 100644
--- a/lisp/eshell/esh-proc.el
+++ b/lisp/eshell/esh-proc.el
@@ -350,6 +350,13 @@ Used only on systems which do not support async subprocesses.")
350 'process (format-message "started external process `%s'" proc)) 350 'process (format-message "started external process `%s'" proc))
351 (eshell-record-process-object proc) 351 (eshell-record-process-object proc)
352 (eshell-record-process-properties proc) 352 (eshell-record-process-properties proc)
353 (when stderr-proc
354 ;; Provide a shared flag between the primary and stderr
355 ;; processes. This lets the primary process wait to clean up
356 ;; until stderr is totally finished (see `eshell-sentinel').
357 (let ((stderr-live (list t)))
358 (process-put proc :eshell-stderr-live stderr-live)
359 (process-put stderr-proc :eshell-stderr-live stderr-live)))
353 (run-hook-with-args 'eshell-exec-hook proc) 360 (run-hook-with-args 'eshell-exec-hook proc)
354 (when (fboundp 'process-coding-system) 361 (when (fboundp 'process-coding-system)
355 (let ((coding-systems (process-coding-system proc))) 362 (let ((coding-systems (process-coding-system proc)))
@@ -491,11 +498,12 @@ PROC is the process that's exiting. STRING is the exit message."
491 (unwind-protect 498 (unwind-protect
492 (let* ((handles (process-get proc :eshell-handles)) 499 (let* ((handles (process-get proc :eshell-handles))
493 (index (process-get proc :eshell-handle-index)) 500 (index (process-get proc :eshell-handle-index))
501 (primary (= index eshell-output-handle))
494 (data (process-get proc :eshell-pending)) 502 (data (process-get proc :eshell-pending))
495 ;; Only get the status for the primary subprocess, 503 ;; Only get the status for the primary subprocess,
496 ;; not the pipe process (if any). 504 ;; not the pipe process (if any).
497 (status (when (= index eshell-output-handle) 505 (status (when primary (process-exit-status proc)))
498 (process-exit-status proc)))) 506 (stderr-live (process-get proc :eshell-stderr-live)))
499 ;; Write the exit message for the last process in the 507 ;; Write the exit message for the last process in the
500 ;; foreground pipeline if its status is abnormal and 508 ;; foreground pipeline if its status is abnormal and
501 ;; stderr is already writing to the terminal. 509 ;; stderr is already writing to the terminal.
@@ -507,9 +515,12 @@ PROC is the process that's exiting. STRING is the exit message."
507 (process-put proc :eshell-pending nil) 515 (process-put proc :eshell-pending nil)
508 ;; If we're in the middle of handling output from this 516 ;; If we're in the middle of handling output from this
509 ;; process then schedule the EOF for later. 517 ;; process then schedule the EOF for later.
510 (letrec ((finish-io 518 (letrec ((wait-for-stderr (and primary
519 (not (process-live-p proc))))
520 (finish-io
511 (lambda () 521 (lambda ()
512 (if (process-get proc :eshell-busy) 522 (if (or (process-get proc :eshell-busy)
523 (and wait-for-stderr (car stderr-live)))
513 (run-at-time 0 nil finish-io) 524 (run-at-time 0 nil finish-io)
514 (when data 525 (when data
515 (ignore-error eshell-pipe-broken 526 (ignore-error eshell-pipe-broken
@@ -519,11 +530,13 @@ PROC is the process that's exiting. STRING is the exit message."
519 status 530 status
520 (when status (list 'quote (= status 0))) 531 (when status (list 'quote (= status 0)))
521 handles) 532 handles)
522 (eshell-kill-process-function proc string) 533 (eshell-debug-command
523 (eshell-debug-command 534 'process
524 'process 535 (format-message
525 (format-message 536 "finished external process `%s'" proc))
526 "finished external process `%s'" proc)))))) 537 (if primary
538 (eshell-kill-process-function proc string)
539 (setcar stderr-live nil))))))
527 (funcall finish-io))) 540 (funcall finish-io)))
528 (when-let ((entry (assq proc eshell-process-list))) 541 (when-let ((entry (assq proc eshell-process-list)))
529 (eshell-remove-process-entry entry)))))) 542 (eshell-remove-process-entry entry))))))