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