Function: tramp-smb-handle-process-file

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

Signature

(tramp-smb-handle-process-file PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS)

Documentation

Like process-file for Tramp files.

Source Code

;; Defined in /usr/src/emacs/lisp/net/tramp-smb.el.gz
(defun tramp-smb-handle-process-file
  (program &optional infile destination display &rest args)
  "Like `process-file' for Tramp files."
  ;; The implementation is not complete yet.
  (when (and (numberp destination) (zerop destination))
    (error "Implementation does not handle immediate return"))

  (with-parsed-tramp-file-name (expand-file-name default-directory) nil
    (let* ((name (file-name-nondirectory program))
	   (name1 name)
	   (i 0)
	   input tmpinput outbuf command ret)

      ;; Determine input.
      (when infile
	(setq infile (tramp-compat-file-name-unquote (expand-file-name infile)))
	(if (tramp-equal-remote default-directory infile)
	    ;; INFILE is on the same remote host.
	    (setq input (tramp-unquote-file-local-name infile))
	  ;; INFILE must be copied to remote host.
	  (setq input (tramp-make-tramp-temp-file v)
		tmpinput (tramp-make-tramp-file-name v input))
	  (copy-file infile tmpinput t))
	;; Transform input into a filename powershell does understand.
	(setq input (format "//%s%s" host input)))

      ;; Determine output.
      (cond
       ;; Just a buffer.
       ((bufferp destination)
	(setq outbuf destination))
       ;; A buffer name.
       ((stringp destination)
	(setq outbuf (get-buffer-create destination)))
       ;; (REAL-DESTINATION ERROR-DESTINATION)
       ((consp destination)
	;; output.
	(cond
	 ((bufferp (car destination))
	  (setq outbuf (car destination)))
	 ((stringp (car destination))
	  (setq outbuf (get-buffer-create (car destination))))
	 ((car destination)
	  (setq outbuf (current-buffer))))
	;; stderr.
	(tramp-message v 2 "%s" "STDERR not supported"))
       ;; 't
       (destination
	(setq outbuf (current-buffer))))

      ;; Construct command.
      (setq command (string-join (cons program args) " ")
	    command (if input
			(format
			 "get-content %s | & %s"
			 (tramp-smb-shell-quote-argument input) command)
		      (format "& %s" command)))

      (while (get-process name1)
	;; NAME must be unique as process name.
	(setq i (1+ i)
	      name1 (format "%s<%d>" name i)))

      ;; Set the new process properties.
      (tramp-set-connection-property v "process-name" name1)
      (tramp-set-connection-property
       v "process-buffer"
       (or outbuf (generate-new-buffer tramp-temp-buffer-name)))

      ;; Call it.
      (condition-case nil
	  (with-current-buffer (tramp-get-connection-buffer v)
	    ;; Preserve buffer contents.
	    (narrow-to-region (point-max) (point-max))
	    (tramp-smb-call-winexe v)
	    (when (tramp-smb-get-share v)
	      (tramp-smb-send-command
	       v (format "cd \"//%s%s\"" host (file-name-directory localname))))
	    (tramp-smb-send-command v command)
	    ;; Preserve command output.
	    (narrow-to-region (point-max) (point-max))
	    (let ((p (tramp-get-connection-process v)))
	      (tramp-smb-send-command v "exit $lasterrorcode")
	      (while (process-live-p p)
		(sleep-for 0.1)
		(setq ret (process-exit-status p))))
	    (delete-region (point-min) (point-max))
	    (widen))

	;; When the user did interrupt, we should do it also.  We use
	;; return code -1 as marker.
	(quit
	 (setq ret -1))
	;; Handle errors.
	(error
	 (setq ret 1)))

      ;; We should redisplay the output.
      (when (and display outbuf (get-buffer-window outbuf t)) (redisplay))

      ;; Cleanup.  We remove all file cache values for the connection,
      ;; because the remote process could have changed them.
      (tramp-flush-connection-property v "process-name")
      (tramp-flush-connection-property v "process-buffer")
      (when tmpinput (delete-file tmpinput))
      (unless outbuf
	(kill-buffer (tramp-get-connection-property v "process-buffer" nil)))
      (when process-file-side-effects
	(tramp-flush-directory-properties v ""))

      ;; Return exit status.
      (if (equal ret -1)
	  (keyboard-quit)
	ret))))