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.
This commit is contained in:
Jim Porter 2023-01-23 17:21:57 -08:00
parent 34b832fce1
commit 39c704e03d
4 changed files with 50 additions and 41 deletions

View file

@ -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."

View file

@ -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")

View file

@ -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))))

View file

@ -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)