emacs: Refactor subprocess stderr propagation

Load subprocess error output to a string in the callers, and propagate
the error messages as a string parameter instead of a path to file
names.

Required to be able to avoid using temporary files for subprocess
error output.

* notmuch-lib.el: Update notmuch-check-async-exit-status,
  notmuch-check-exit-status: accept an err parameter instead of
  err-file; shift the responsibility of loading error messages from
  files up the call stack.
This commit is contained in:
Vladimir Panteleev 2017-08-17 17:57:11 +00:00 committed by David Bremner
parent 938ec0f80c
commit 69946c47c9

View file

@ -768,23 +768,23 @@ signaled error. This function does not return."
(error "%s" (concat msg (when extra (error "%s" (concat msg (when extra
" (see *Notmuch errors* for more details)")))) " (see *Notmuch errors* for more details)"))))
(defun notmuch-check-async-exit-status (proc msg &optional command err-file) (defun notmuch-check-async-exit-status (proc msg &optional command err)
"If PROC exited abnormally, pop up an error buffer and signal an error. "If PROC exited abnormally, pop up an error buffer and signal an error.
This is a wrapper around `notmuch-check-exit-status' for This is a wrapper around `notmuch-check-exit-status' for
asynchronous process sentinels. PROC and MSG must be the asynchronous process sentinels. PROC and MSG must be the
arguments passed to the sentinel. COMMAND and ERR-FILE, if arguments passed to the sentinel. COMMAND and ERR, if provided,
provided, are passed to `notmuch-check-exit-status'. If COMMAND are passed to `notmuch-check-exit-status'. If COMMAND is not
is not provided, it is taken from `process-command'." provided, it is taken from `process-command'."
(let ((exit-status (let ((exit-status
(case (process-status proc) (case (process-status proc)
((exit) (process-exit-status proc)) ((exit) (process-exit-status proc))
((signal) msg)))) ((signal) msg))))
(when exit-status (when exit-status
(notmuch-check-exit-status exit-status (or command (process-command proc)) (notmuch-check-exit-status exit-status (or command (process-command proc))
nil err-file)))) nil err))))
(defun notmuch-check-exit-status (exit-status command &optional output err-file) (defun notmuch-check-exit-status (exit-status command &optional output err)
"If EXIT-STATUS is non-zero, pop up an error buffer and signal an error. "If EXIT-STATUS is non-zero, pop up an error buffer and signal an error.
If EXIT-STATUS is non-zero, pop up a notmuch error buffer If EXIT-STATUS is non-zero, pop up a notmuch error buffer
@ -793,9 +793,9 @@ be a number indicating the exit status code of a process or a
string describing the signal that terminated the process (such as string describing the signal that terminated the process (such as
returned by `call-process'). COMMAND must be a list giving the returned by `call-process'). COMMAND must be a list giving the
command and its arguments. OUTPUT, if provided, is a string command and its arguments. OUTPUT, if provided, is a string
giving the output of command. ERR-FILE, if provided, is the name giving the output of command. ERR, if provided, is the error
of a file containing the error output of command. OUTPUT and the output of command. OUTPUT and ERR will be included in the error
contents of ERR-FILE will be included in the error message." message."
(cond (cond
((eq exit-status 0) t) ((eq exit-status 0) t)
@ -808,12 +808,7 @@ You may need to restart Emacs or upgrade your notmuch Emacs package."))
Emacs requested a newer output format than supported by the notmuch CLI. Emacs requested a newer output format than supported by the notmuch CLI.
You may need to restart Emacs or upgrade your notmuch package.")) You may need to restart Emacs or upgrade your notmuch package."))
(t (t
(let* ((err (when err-file (let* ((command-string
(with-temp-buffer
(insert-file-contents err-file)
(unless (eobp)
(buffer-string)))))
(command-string
(mapconcat (lambda (arg) (mapconcat (lambda (arg)
(shell-quote-argument (shell-quote-argument
(cond ((stringp arg) arg) (cond ((stringp arg) arg)
@ -889,9 +884,13 @@ error."
(with-temp-buffer (with-temp-buffer
(let ((err-file (make-temp-file "nmerr"))) (let ((err-file (make-temp-file "nmerr")))
(unwind-protect (unwind-protect
(let ((status (notmuch-call-notmuch--helper (list t err-file) args))) (let ((status (notmuch-call-notmuch--helper (list t err-file) args))
(err (with-temp-buffer
(insert-file-contents err-file)
(unless (eobp)
(buffer-string)))))
(notmuch-check-exit-status status (cons notmuch-command args) (notmuch-check-exit-status status (cons notmuch-command args)
(buffer-string) err-file) (buffer-string) err)
(goto-char (point-min)) (goto-char (point-min))
(read (current-buffer))) (read (current-buffer)))
(delete-file err-file))))) (delete-file err-file)))))
@ -931,9 +930,14 @@ status."
proc)) proc))
(defun notmuch-start-notmuch-sentinel (proc event) (defun notmuch-start-notmuch-sentinel (proc event)
(let ((err-file (process-get proc 'err-file)) "Process sentinel function used by `notmuch-start-notmuch'."
(sub-sentinel (process-get proc 'sub-sentinel)) (let* ((err-file (process-get proc 'err-file))
(real-command (process-get proc 'real-command))) (err (with-temp-buffer
(insert-file-contents err-file)
(unless (eobp)
(buffer-string))))
(sub-sentinel (process-get proc 'sub-sentinel))
(real-command (process-get proc 'real-command)))
(condition-case err (condition-case err
(progn (progn
;; Invoke the sub-sentinel, if any ;; Invoke the sub-sentinel, if any
@ -945,12 +949,13 @@ status."
;; and there's no point in telling the user that (but we ;; and there's no point in telling the user that (but we
;; still check for and report stderr output below). ;; still check for and report stderr output below).
(when (buffer-live-p (process-buffer proc)) (when (buffer-live-p (process-buffer proc))
(notmuch-check-async-exit-status proc event real-command err-file)) (notmuch-check-async-exit-status proc event real-command err))
;; If that didn't signal an error, then any error output was ;; If that didn't signal an error, then any error output was
;; really warning output. Show warnings, if any. ;; really warning output. Show warnings, if any.
(let ((warnings (let ((warnings
(with-temp-buffer (with-temp-buffer
(unless (= (second (insert-file-contents err-file)) 0) (unless (= (second (insert-file-contents err-file)) 0)
(goto-char (point-min))
(end-of-line) (end-of-line)
;; Show first line; stuff remaining lines in the ;; Show first line; stuff remaining lines in the
;; errors buffer. ;; errors buffer.