diff options
| author | Jim Porter | 2023-09-11 22:05:38 -0700 |
|---|---|---|
| committer | Jim Porter | 2023-09-12 11:44:27 -0700 |
| commit | fad91b56d13e7bc902cce522671ebf47b0632d45 (patch) | |
| tree | c4ac8e4ddcf633c21254f349edfc515c4ec034e1 | |
| parent | a0c8b458209b127834af7a70be6024bf65ae06b7 (diff) | |
| download | emacs-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.el | 31 |
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)))))) |