From 4a5cc876c9eed8e1f0d493ab63a99434821f620e Mon Sep 17 00:00:00 2001 From: Jim Porter Date: Mon, 23 Jan 2023 17:21:57 -0800 Subject: [PATCH] Split out exit code parts of 'eshell-close-handles' into a new function * lisp/eshell/esh-cmd.el (eshell-last-command-status) (eshell-last-command-result): Move here from esh-io.el. (eshell-set-exit-info): New function, extracted from 'eshell-close-handles'. * lisp/eshell/esh-io.el (eshell-close-handles): Make old calling convention obsolete. Update callers to use 'eshell-set-exit-info' as needed. (cherry picked from commit 39c704e03de59a1cc46494fb71426e7a7fe8013d) --- lisp/eshell/em-alias.el | 3 ++- lisp/eshell/esh-cmd.el | 31 +++++++++++++++++++++---------- lisp/eshell/esh-io.el | 38 ++++++++++++++++++-------------------- lisp/eshell/esh-proc.el | 19 +++++++++---------- 4 files changed, 50 insertions(+), 41 deletions(-) diff --git a/lisp/eshell/em-alias.el b/lisp/eshell/em-alias.el index ff0620702cf..aa6eb2d4efb 100644 --- a/lisp/eshell/em-alias.el +++ b/lisp/eshell/em-alias.el @@ -211,7 +211,8 @@ This is useful after manually editing the contents of the file." (let ((eshell-current-handles (eshell-create-handles eshell-aliases-file 'overwrite))) (eshell/alias) - (eshell-close-handles 0 'nil)))) + (eshell-set-exit-info 0 nil) + (eshell-close-handles)))) (defsubst eshell-lookup-alias (name) "Check whether NAME is aliased. Return the alias if there is one." diff --git a/lisp/eshell/esh-cmd.el b/lisp/eshell/esh-cmd.el index 099e97a083d..d21ac850c02 100644 --- a/lisp/eshell/esh-cmd.el +++ b/lisp/eshell/esh-cmd.el @@ -104,7 +104,6 @@ (require 'esh-arg) (require 'esh-proc) (require 'esh-module) -(require 'esh-io) (require 'esh-ext) (require 'eldoc) @@ -276,8 +275,13 @@ Each element is of the form (FORM PROCESSES), as with Has the value `first', `last' for the first/last commands in the pipeline, otherwise t.") (defvar eshell-in-subcommand-p nil) + (defvar eshell-last-arguments nil) (defvar eshell-last-command-name nil) +(defvar-local eshell-last-command-status 0 + "The exit code from the last command. 0 if successful.") +(defvar-local eshell-last-command-result nil + "The result of the last command. Not related to success.") (defvar eshell-deferrable-commands '(eshell-deferrable) "A list of functions which might return a deferrable process. @@ -518,7 +522,6 @@ the second is ignored." `(eshell-commands ,(cadr (cadr arg)) ,silent)) arg)) -(defvar eshell-last-command-status) ;Define in esh-io.el. (defvar eshell--local-vars nil "List of locally bound vars that should take precedence over env-vars.") @@ -610,7 +613,13 @@ must be implemented via rewriting, rather than as a function." `(eshell-protect ,(eshell-invokify-arg (car (last terms)) t)))))) -(defvar eshell-last-command-result) ;Defined in esh-io.el. +(defun eshell-set-exit-info (status &optional result) + "Set the exit status and result for the last command. +STATUS is the process exit code (zero, if the command completed +successfully). RESULT is the value of the last command." + (when status + (setq eshell-last-command-status status)) + (setq eshell-last-command-result result)) (defun eshell-exit-success-p () "Return non-nil if the last command was successful. @@ -787,7 +796,8 @@ this grossness will be made to disappear by using `call/cc'..." (mapc #'funcall eshell-this-command-hook))) (error (eshell-errorn (error-message-string err)) - (eshell-close-handles 1)))) + (eshell-set-exit-info 1) + (eshell-close-handles)))) (define-obsolete-function-alias 'eshell-trap-errors #'eshell-do-command "31.1") @@ -1415,10 +1425,10 @@ case." ;; command status to some non-zero value to indicate an error; to ;; match GNU/Linux, we use 141, which the numeric value of ;; SIGPIPE on GNU/Linux (13) with the high bit (2^7) set. - (setq eshell-last-command-status 141) + (eshell-set-exit-info 141) nil) (error - (setq eshell-last-command-status 1) + (eshell-set-exit-info 1) (let ((msg (error-message-string err))) (if (and (not form-p) (string-match "^Wrong number of arguments" msg) @@ -1497,8 +1507,8 @@ a string naming a Lisp function." (unless eshell-allow-commands (signal 'eshell-commands-forbidden '(lisp))) (catch 'eshell-external ; deferred to an external command - (setq eshell-last-command-status 0 - eshell-last-arguments args) + (eshell-set-exit-info 0) + (setq eshell-last-arguments args) (let* ((eshell-ensure-newline-p t) (command-form-p (functionp object)) (result @@ -1533,7 +1543,7 @@ a string naming a Lisp function." (eshell-eval* #'eshell-print-maybe-n #'eshell-error-maybe-n object)))) - (eshell-close-handles + (eshell-set-exit-info ;; If `eshell-lisp-form-nil-is-failure' is non-nil, Lisp forms ;; that succeeded but have a nil result should have an exit ;; status of 2. @@ -1542,7 +1552,8 @@ a string naming a Lisp function." (= eshell-last-command-status 0) (not result)) 2) - (list 'quote result))))) + result) + (eshell-close-handles)))) (define-obsolete-function-alias 'eshell-lisp-command* #'eshell-lisp-command "31.1") diff --git a/lisp/eshell/esh-io.el b/lisp/eshell/esh-io.el index 9de9cc4509a..cf7336bd70d 100644 --- a/lisp/eshell/esh-io.el +++ b/lisp/eshell/esh-io.el @@ -200,12 +200,6 @@ describing the mode, e.g. for using with `eshell-get-target'.") (defvar eshell-current-handles nil) -(defvar-local eshell-last-command-status 0 - "The exit code from the last command. 0 if successful.") - -(defvar eshell-last-command-result nil - "The result of the last command. Not related to success.") - (defvar eshell-output-file-buffer nil "If non-nil, the current buffer is a file output buffer.") @@ -382,23 +376,27 @@ is not shared with the original handles." (cl-incf (cdar handle)))) handles) -(defun eshell-close-handles (&optional exit-code result handles) +(declare-function eshell-exit-success-p "esh-cmd") + +(defun eshell-close-handles (&optional handles obsolete-1 obsolete-2) "Close all of the current HANDLES, taking refcounts into account. -If HANDLES is nil, use `eshell-current-handles'. +If HANDLES is nil, use `eshell-current-handles'." + (declare (advertised-calling-convention (&optional handles) "30.1")) + (when (or obsolete-1 obsolete-2 (numberp handles)) + (declare-function eshell-set-exit-info "esh-cmd" + (&optional exit-code result)) + ;; In addition to setting the advertised calling convention, warn + ;; if we get here. A caller may have called with the right number + ;; of arguments but the wrong type. + (display-warning '(eshell close-handles) + "Called `eshell-close-handles' with obsolete arguments") + ;; Here, HANDLES is really the exit code. + (when (or handles obsolete-1) + (eshell-set-exit-info (or handles 0) (cadr obsolete-1))) + (setq handles obsolete-2)) -EXIT-CODE is the process exit code (zero, if the command -completed successfully). If nil, then use the exit code already -set in `eshell-last-command-status'. - -RESULT is the quoted value of the last command. If nil, then use -the value already set in `eshell-last-command-result'." - (when exit-code - (setq eshell-last-command-status exit-code)) - (when result - (cl-assert (eq (car result) 'quote)) - (setq eshell-last-command-result (cadr result))) (let ((handles (or handles eshell-current-handles)) - (succeeded (= eshell-last-command-status 0))) + (succeeded (eshell-exit-success-p))) (dotimes (idx eshell-number-of-handles) (eshell-close-handle (aref handles idx) succeeded)))) diff --git a/lisp/eshell/esh-proc.el b/lisp/eshell/esh-proc.el index ed417ab0f12..2735be882b6 100644 --- a/lisp/eshell/esh-proc.el +++ b/lisp/eshell/esh-proc.el @@ -129,6 +129,7 @@ To add or remove elements of this list, see (declare-function eshell-reset "esh-mode" (&optional no-hooks)) (declare-function eshell-send-eof-to-process "esh-mode") (declare-function eshell-interactive-filter "esh-mode" (buffer string)) +(declare-function eshell-set-exit-info "esh-cmd" (status result)) (declare-function eshell-tail-process "esh-cmd") (defvar-keymap eshell-proc-mode-map @@ -460,10 +461,11 @@ Used only on systems which do not support async subprocesses.") (setq lbeg lend) (set-buffer proc-buf)) (set-buffer oldbuf)) - ;; Simulate the effect of eshell-sentinel. - (eshell-close-handles + ;; Simulate the effect of `eshell-sentinel'. + (eshell-set-exit-info (if (numberp exit-status) exit-status -1) - (list 'quote (and (numberp exit-status) (= exit-status 0)))) + (and (numberp exit-status) (= exit-status 0))) + (eshell-close-handles) (run-hook-with-args 'eshell-kill-hook command exit-status) (or (bound-and-true-p eshell-in-pipeline-p) (setq eshell-last-sync-output-start nil)) @@ -545,9 +547,6 @@ PROC is the process that's exiting. STRING is the exit message." (index (process-get proc :eshell-handle-index)) (primary (= index eshell-output-handle)) (data (process-get proc :eshell-pending)) - ;; Only get the status for the primary subprocess, - ;; not the pipe process (if any). - (status (when primary (process-exit-status proc))) (stderr-live (process-get proc :eshell-stderr-live))) ;; Write the exit message for the last process in the ;; foreground pipeline if its status is abnormal and @@ -577,10 +576,10 @@ PROC is the process that's exiting. STRING is the exit message." (ignore-error eshell-pipe-broken (eshell-output-object data index handles))) - (eshell-close-handles - status - (when status (list 'quote (= status 0))) - handles) + (when primary + (let ((status (process-exit-status proc))) + (eshell-set-exit-info status (= status 0)))) + (eshell-close-handles handles) ;; Clear the handles to mark that we're 100% ;; finished with the I/O for this process. (process-put proc :eshell-handles nil) -- 2.39.5