Function: tramp-handle-insert-file-contents

tramp-handle-insert-file-contents is a byte-compiled function defined in tramp.el.gz.

Signature

(tramp-handle-insert-file-contents FILENAME &optional VISIT BEG END REPLACE)

Documentation

Like insert-file-contents for Tramp files.

Source Code

;; Defined in /usr/src/emacs/lisp/net/tramp.el.gz
(defun tramp-handle-insert-file-contents
  (filename &optional visit beg end replace)
  "Like `insert-file-contents' for Tramp files."
  (barf-if-buffer-read-only)
  (setq filename (expand-file-name filename))
  (let (result local-copy remote-copy)
    (with-parsed-tramp-file-name filename nil
      (unwind-protect
	  (if (not (file-exists-p filename))
              (let ((tramp-verbose (if visit 0 tramp-verbose)))
                (tramp-compat-file-missing v filename))

	    (with-tramp-progress-reporter
		v 3 (format-message "Inserting `%s'" filename)
	      (condition-case err
		  (if (and (tramp-local-host-p v)
			   (let (file-name-handler-alist)
			     (file-readable-p localname)))
		      ;; Short track: if we are on the local host, we can
		      ;; run directly.
		      (setq result
			    (tramp-run-real-handler
			     #'insert-file-contents
			     (list localname visit beg end replace)))

		    ;; When we shall insert only a part of the file, we
		    ;; copy this part.  This works only for the shell file
                    ;; name handlers.  It doesn't work for encrypted files.
		    (when (and (or beg end)
			       (tramp-sh-file-name-handler-p v)
			       (null tramp-crypt-enabled))
		      (setq remote-copy (tramp-make-tramp-temp-file v))
		      ;; This is defined in tramp-sh.el.  Let's assume
		      ;; this is loaded already.
		      (tramp-compat-funcall
		       'tramp-send-command
		       v
		       (cond
			((and beg end)
			 (format "dd bs=1 skip=%d if=%s count=%d of=%s"
				 beg (tramp-shell-quote-argument localname)
				 (- end beg) remote-copy))
			(beg
			 (format "dd bs=1 skip=%d if=%s of=%s"
				 beg (tramp-shell-quote-argument localname)
				 remote-copy))
			(end
			 (format "dd bs=1 count=%d if=%s of=%s"
				 end (tramp-shell-quote-argument localname)
				 remote-copy))))
		      (setq tramp-temp-buffer-file-name nil beg nil end nil))

		    ;; `insert-file-contents-literally' takes care to
		    ;; avoid calling jka-compr.el and epa.el.  By
		    ;; let-binding `inhibit-file-name-operation', we
		    ;; propagate that care to the `file-local-copy'
		    ;; operation.
		    (setq local-copy
			  (let ((inhibit-file-name-operation
				 (when (eq inhibit-file-name-operation
					   'insert-file-contents)
				   'file-local-copy)))
			    (cond
			     ((stringp remote-copy)
			      (file-local-copy
			       (tramp-make-tramp-file-name
				v remote-copy 'nohop)))
			     ((stringp tramp-temp-buffer-file-name)
			      (copy-file
			       filename tramp-temp-buffer-file-name 'ok)
			      tramp-temp-buffer-file-name)
			     (t (file-local-copy filename)))))

		    ;; When the file is not readable for the owner, it
		    ;; cannot be inserted, even if it is readable for the
		    ;; group or for everybody.
		    (set-file-modes local-copy #o0600)

		    (when (and (null remote-copy)
			       (tramp-get-method-parameter
				v 'tramp-copy-keep-tmpfile))
		      ;; We keep the local file for performance reasons,
		      ;; useful for "rsync".
		      (setq tramp-temp-buffer-file-name local-copy))

		    ;; We must ensure that `file-coding-system-alist'
		    ;; matches `local-copy'.
		    (let ((file-coding-system-alist
			   (tramp-find-file-name-coding-system-alist
			    filename local-copy)))
		      (setq result
			    (insert-file-contents
			     local-copy visit beg end replace))))
		(error
		 (add-hook 'find-file-not-found-functions
			   `(lambda () (signal ',(car err) ',(cdr err)))
			   nil t)
		 (signal (car err) (cdr err))))))

	;; Save exit.
	(when visit
	  (setq buffer-file-name filename
		buffer-read-only (not (file-writable-p filename)))
	  (set-visited-file-modtime)
	  (set-buffer-modified-p nil))
	(when (and (stringp local-copy)
		   (or remote-copy (null tramp-temp-buffer-file-name)))
	  (delete-file local-copy))
	(when (stringp remote-copy)
	  (delete-file (tramp-make-tramp-file-name v remote-copy 'nohop))))

      ;; Result.
      (cons filename (cdr result)))))