Function: majutsu--process-file-responsive
majutsu--process-file-responsive is a natively compiled function
defined in majutsu-process.el.
Signature
(majutsu--process-file-responsive PROGRAM INFILE DESTINATION &rest ARGS)
Documentation
Run PROGRAM with ARGS synchronously while servicing Emacs subprocesses.
DESTINATION follows the process-file stdout/stderr contract supported by
majutsu--process-file-supported-p. When stderr is requested as a file,
the standard error process spawned by make-process has its sentinel
silenced so the captured stderr is verbatim, and is drained explicitly
before the file is written so its output cannot lag behind. If a non-atomic
wrapper signals after creating a process, reclaim that process only when its
private stderr process and requested attributes identify it uniquely.
Source Code
;; Defined in /nix/store/jagqw3nms546pad0gxi5f3wsckk6pji7-emacs-packages-deps/share/emacs/site-lisp/majutsu-process.el
(defun majutsu--process-file-responsive (program _infile destination &rest args)
"Run PROGRAM with ARGS synchronously while servicing Emacs subprocesses.
DESTINATION follows the `process-file' stdout/stderr contract supported by
`majutsu--process-file-supported-p'. When stderr is requested as a file,
the standard error process spawned by `make-process' has its sentinel
silenced so the captured stderr is verbatim, and is drained explicitly
before the file is written so its output cannot lag behind. If a non-atomic
wrapper signals after creating a process, reclaim that process only when its
private stderr process and requested attributes identify it uniquely."
(let* ((stdout-dest (if (consp destination) (car destination) destination))
(stderr-dest (and (consp destination) (cadr destination)))
(stderr-discard (and (consp destination) (null stderr-dest)))
(stdout-buffer (majutsu--process-destination-buffer stdout-dest))
(stdout-marker (and stdout-buffer
(copy-marker (with-current-buffer stdout-buffer
(point))
t)))
(stdout-filter (and stdout-marker
(majutsu--process-file-insert-filter stdout-marker)))
(stderr-buffer (and (or (stringp stderr-dest) stderr-discard)
(generate-new-buffer " *majutsu-stderr*")))
(process-name (file-name-nondirectory program))
(command (cons program args))
(processes-before (process-list))
process
stderr-process
exit)
(unwind-protect
(progn
;; Create the process inside the protected region. In particular,
;; a file-handler or invalid executable can make `make-process'
;; signal after the temporary stderr buffer has been allocated.
(condition-case err
(setq process
(make-process
:name process-name
:buffer stdout-buffer
:command command
:connection-type 'pipe
:coding default-process-coding-system
:noquery t
:filter stdout-filter
:sentinel #'ignore
:stderr stderr-buffer
:file-handler t))
(error
;; A file handler or wrapper can create the real process and
;; signal before returning it. Recover that process only when
;; its private stderr process and all requested attributes make
;; the association unambiguous; otherwise leave PROCESS nil so
;; cleanup cannot kill an unrelated process.
(setq stderr-process
(and stderr-buffer (get-buffer-process stderr-buffer)))
(setq process
(majutsu--process-file-created-main-process
processes-before stderr-buffer stderr-process
stdout-buffer stdout-filter command process-name))
(signal (car err) (cdr err))))
(setq stderr-process
(and stderr-buffer (get-buffer-process stderr-buffer)))
;; Emacs' default sentinel on the standard error process appends a
;; "Process ... finished" line to the stderr buffer; silence it so
;; captured stderr is verbatim.
(when stderr-process
(set-process-sentinel stderr-process #'ignore))
;; The main process may have already exited (e.g. it does not
;; read stdin); guard `process-send-eof' so we never signal
;; "Process ... not running" from the dispatch path.
(when (process-live-p process)
(condition-case nil
(process-send-eof process)
(error nil)))
(setq exit (majutsu--process-wait process stderr-process))
(when (and stderr-buffer (stringp stderr-dest))
(with-current-buffer stderr-buffer
(write-region (point-min) (point-max) stderr-dest nil 'silent)))
exit)
(when (and process (process-live-p process))
(delete-process process))
(when (and stderr-process (process-live-p stderr-process))
(delete-process stderr-process))
(when stdout-marker
(set-marker stdout-marker nil))
(when (buffer-live-p stderr-buffer)
(kill-buffer stderr-buffer)))))