Function: tramp-handle-make-process

tramp-handle-make-process is a byte-compiled function defined in tramp.el.gz.

Signature

(tramp-handle-make-process &rest ARGS)

Documentation

An alternative make-process implementation for Tramp files.

Source Code

;; Defined in /usr/src/emacs/lisp/net/tramp.el.gz
(defun tramp-handle-make-process (&rest args)
  "An alternative `make-process' implementation for Tramp files."
  (tramp-skeleton-make-process args nil nil
    ;; Check for `tramp-sh-file-name-handler' and
    ;; `adb-file-name-handler-p', because something is different
    ;; between tramp-sh.el, and tramp-adb.el or tramp-sshfs.el.
    (let* ((default-directory tramp-compat-temporary-file-directory)
	   (sh-file-name-handler-p (tramp-sh-file-name-handler-p v))
	   (adb-file-name-handler-p (tramp-adb-file-name-p v))
	   (env (mapcar
		 (lambda (elt)
		   (when (string-search "=" elt) elt))
		 tramp-remote-process-environment))
	   ;; We use as environment the difference to toplevel
	   ;; `process-environment'.
	   (env (dolist (elt process-environment env)
		  (when (and
			 (string-search "=" elt)
			 (not (tramp-local-environment-variable-p elt)))
		    (setq env (cons elt env)))))
	   ;; Add remote path if exists.
	   (env (if-let* ((sh-file-name-handler-p)
			  (remote-path
			   (string-join (tramp-get-remote-path v) ":")))
		    (setenv-internal env "PATH" remote-path 'keep)
		  env))
	   ;; Add HISTFILE if indicated.
	   (env (if sh-file-name-handler-p
		    (cond
		     ((stringp tramp-histfile-override)
		      (setenv-internal
		       env "HISTFILE" tramp-histfile-override 'keep))
		     (tramp-histfile-override
		      (setq env (setenv-internal env "HISTFILE" "''" 'keep))
		      (setq env (setenv-internal env "HISTSIZE" "0" 'keep))
		      (setenv-internal env "HISTFILESIZE" "0" 'keep))
		     (t env))
		  env))
	   ;; Add INSIDE_EMACS.
	   (env (setenv-internal env "INSIDE_EMACS" (tramp-inside-emacs) 'keep))
	   (env (mapcar #'tramp-shell-quote-argument (delq nil env)))
	   ;; Quote command.
	   (command (mapconcat #'tramp-shell-quote-argument command " "))
	   ;; Set cwd and environment variables.
	   (command
	    (append
	     `("cd" ,(tramp-shell-quote-argument localname) "&&" "(" "env")
	     env `(,command ")")))
	   ;; Add remote shell if needed.
	   (command
	    (if (consp (tramp-get-method-parameter v 'tramp-direct-async))
		(append
		 (tramp-get-method-parameter v 'tramp-direct-async)
                 `(,(string-join command " ")))
	      command))
	   (login-program
	    (tramp-get-method-parameter v 'tramp-login-program))
	   ;; We don't create the temporary file.  In fact, it is just
	   ;; a prefix for the ControlPath option of ssh; the real
	   ;; temporary file has another name, and it is created and
	   ;; protected by ssh.  It is also removed by ssh when the
	   ;; connection is closed.  The temporary file name is cached
	   ;; in the main connection process, therefore we cannot use
	   ;; `tramp-get-connection-process'.
	   (tmpfile
	    (when sh-file-name-handler-p
	      (with-tramp-connection-property
		  (tramp-get-process v) "temp-file"
		(tramp-compat-make-temp-name))))
	   (options
	    (when sh-file-name-handler-p
	      (tramp-compat-funcall
		  'tramp-ssh-controlmaster-options v)))
	   (device
	    (when adb-file-name-handler-p
	      (tramp-compat-funcall
		  'tramp-adb-get-device v)))
           (pta (unless (eq connection-type 'pipe) "-t"))
	   login-args p)

      ;; Command could be too long, for example due to a longish PATH.
      (when (and sh-file-name-handler-p
		 (length> (string-join command) (tramp-get-remote-pipe-buf v)))
	(signal 'error (cons "Command too long:" command)))

      (setq
       ;; Replace `login-args' place holders.  Split ControlMaster
       ;; options.
       login-args
       (append
	(flatten-tree (tramp-get-method-parameter v 'tramp-async-args))
	(flatten-tree
	 (mapcar
	  (lambda (x) (split-string x " "))
	  (tramp-expand-args
	   v 'tramp-login-args nil
	   ?h (or host "") ?u (or user "") ?p (or port "")
	   ?c (format-spec (or options "") (format-spec-make ?t tmpfile))
	   ?d (or device "") ?a (or pta "") ?l ""))))
       ;; Suppress `internal-default-process-sentinel', which is set
       ;; when :sentinel is nil.  (Bug#71049)
       p (make-process
	  :name name :buffer buffer
	  :command (append `(,login-program) login-args command)
	  :coding coding :noquery noquery :connection-type connection-type
	  :sentinel (or sentinel #'ignore) :stderr stderr))
      ;; Set filter.  Prior Emacs 29.1, it doesn't work reliably to
      ;; provide it as `make-process' argument when filter is t.  See
      ;; Bug#51177.
      (when filter
	(set-process-filter p filter))
      (tramp-post-process-creation p v)
      ;; Query flag is overwritten in `tramp-post-process-creation',
      ;; so we reset it.
      (set-process-query-on-exit-flag p (null noquery))
      (process-put p 'remote-command orig-command)
      (when (bufferp stderr)
	(tramp-taint-remote-process-buffer stderr))

      p)))