When you pass :stderr
to make-process
, it creates a pipe process to filter standard error. That pipe process has its own sentinel, which isn't set explicitly so defaults to internal-default-process-sentinel
. That function inserts the text Process *my-process* stderr finished
. As of Emacs 26.3, I can't find a way to override this: the stderr process doesn't seem to be available from Lisp.
It does seem however that the original process sentinel runs before the pipe process sentinel. (That's from an experiment on Emacs 26.3, it may well turn out to depend on the Emacs version or on other circumstances, I haven't dug into the details.) Here's a proof-of-concept that seems to work.
(make-variable-buffer-local 'process-associated-stderr-buffer)
(make-variable-buffer-local 'process-associated-stderr-buffer-size)
(defun has-empty-stderr-sentinel (process event)
(setq process-associated-stderr-buffer-size (buffer-size process-associated-stderr-buffer)))
(defun has-empty-stderr (&rest command)
(with-temp-buffer
(let ((stderr-buffer (current-buffer)))
(with-temp-buffer
(setq process-associated-stderr-buffer stderr-buffer)
(let ((process (make-process :name "myprocess"
:command command
:stderr stderr-buffer
:sentinel 'has-empty-stderr-sentinel)))
(while (process-live-p process)
(sit-for 0.1)))
(= 0 process-associated-stderr-buffer-size)))))
(has-empty-stderr "ls" "/") ; → t
(has-empty-stderr "ls" "/does not exist") ; → nil
This is cumbersome enough that you might as well pass your own pipe process to make-process
. Call make-pipe-process
with a :sentinel
argument that checks the process buffer size.
(defun sentinel-is-empty (process event)
(when (equal event "finished\n")
(with-current-buffer (process-buffer process)
(when (= 0 (buffer-size))
…))))
(with-temp-buffer
(let ((stderr-buffer (current-buffer)))
(let* ((stderr-process (make-pipe-process :buffer stderr-buffer
:noquery t
:sentinel sentinel-is-empty)))
(process (make-process … :stderr stderr-process)))
…)))
cl-letf
to overrideinternal-default-process-sentinel
can be used to remove the extra text (./test/lisp/net/tramp-tests.el
in emacs repo does this), although I'd rather not have to override internal functions if there is a cleaner way to resolve.