# HG changeset patch # User Michael Albinus # Date 1256310248 0 # Node ID 828d51e45d15896c9456429bf7b308e53b9ccd6d # Parent 34b6eefd60c21b2794b8fb95454c0d7379a9eb19 * net/tramp.el (top): Remove `tramp-rfn-eshadow-update-overlay' from `rfn-eshadow-update-overlay-hook' when unloading. (tramp-methods): Add `tramp-copy-keep-tmpfile' for "rsync" and "rsyncc". Adjust doc string. (tramp-temp-buffer-file-name) New buffer-local defvar. (tramp-handle-insert-file-contents, tramp-handle-write-region): Keep temporary file when indicated by method ("rsync" and "rsyncc"). (tramp-handle-write-region): Handle APPEND. (tramp-delete-temp-file-function): New defun. Added to `kill-buffer-hook'. diff -r 34b6eefd60c2 -r 828d51e45d15 lisp/net/tramp.el --- a/lisp/net/tramp.el Fri Oct 23 08:20:11 2009 +0000 +++ b/lisp/net/tramp.el Fri Oct 23 15:04:08 2009 +0000 @@ -386,6 +386,7 @@ (tramp-copy-program "rsync") (tramp-copy-args (("-e" "ssh") ("-t" "%k") ("-r"))) (tramp-copy-keep-date t) + (tramp-copy-keep-tmpfile t) (tramp-copy-recursive t) (tramp-password-end-of-line nil)) ("rsyncc" @@ -403,6 +404,7 @@ " -o ControlPath=%t.%%r@%%h:%%p" " -o ControlMaster=auto")))) (tramp-copy-keep-date t) + (tramp-copy-keep-tmpfile t) (tramp-copy-recursive t) (tramp-password-end-of-line nil)) ("remcp" (tramp-login-program "remsh") @@ -654,6 +656,11 @@ * `tramp-copy-keep-date' This specifies whether the copying program when the preserves the timestamp of the original file. + * `tramp-copy-keep-tmpfile' + This specifies whether a temporary local file shall be kept + for optimization reasons (useful for \"rsync\" methods). + * `tramp-copy-recursive' + Whether the operation copies directories recursively. * `tramp-default-port' The default port of a method is needed in case of gateway connections. Additionally, it is used as indication which method is prepared for @@ -1146,6 +1153,11 @@ "Buffer name for a temporary buffer. It shall be used in combination with `generate-new-buffer-name'.") +(defvar tramp-temp-buffer-file-name nil + "File name of a persistent local temporary file. +Useful for \"rsync\" like methods.") +(make-variable-buffer-local 'tramp-temp-buffer-file-name) + (defcustom tramp-sh-extra-args '(("/bash\\'" . "-norc -noprofile")) "*Alist specifying extra arguments to pass to the remote shell. Entries are (REGEXP . ARGS) where REGEXP is a regular expression @@ -1942,7 +1954,7 @@ ;; Handlers for foreign methods, like FTP or SMB, shall be plugged here. (defvar tramp-foreign-file-name-handler-alist ;; (identity . tramp-sh-file-name-handler) should always be the last - ;; entry, since `identity' always matches. + ;; entry, because `identity' always matches. '((identity . tramp-sh-file-name-handler)) "Alist of elements (FUNCTION . HANDLER) for foreign methods handled specially. If (FUNCTION FILENAME) returns non-nil, then all I/O on that file is done by @@ -2295,7 +2307,11 @@ (when (boundp 'rfn-eshadow-update-overlay-hook) (add-hook 'rfn-eshadow-update-overlay-hook - 'tramp-rfn-eshadow-update-overlay)) + 'tramp-rfn-eshadow-update-overlay) + (add-hook 'tramp-unload-hook + (lambda () + (remove-hook 'rfn-eshadow-update-overlay-hook + 'tramp-rfn-eshadow-update-overlay)))) ;;; File Name Handler Functions: @@ -4431,11 +4447,25 @@ (when (eq inhibit-file-name-operation 'insert-file-contents) 'file-local-copy))) - (file-local-copy - (if (stringp remote-copy) - (tramp-make-tramp-file-name - method user host remote-copy) - filename)))) + (cond + ((stringp remote-copy) + (file-local-copy + (tramp-make-tramp-file-name + method user host remote-copy))) + ((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 (and (null remote-copy) + (tramp-get-method-parameter + method 'tramp-copy-keep-tmpfile)) + ;; We keep the local file for performance reasons, + ;; useful for "rsync". + (set-file-modes local-copy (tramp-octal-to-decimal "0600")) + (setq tramp-temp-buffer-file-name local-copy) + (put 'tramp-temp-buffer-file-name 'permanent-local t)) + (tramp-message v 4 "Inserting local temp file `%s'..." local-copy) @@ -4465,7 +4495,8 @@ (setq buffer-read-only (not (file-writable-p filename))) (set-visited-file-modtime) (set-buffer-modified-p nil)) - (when (stringp local-copy) + (when (and (stringp local-copy) + (or remote-copy (null tramp-temp-buffer-file-name))) (delete-file local-copy)) (when (stringp remote-copy) (delete-file @@ -4585,15 +4616,12 @@ (defvar tramp-handle-write-region-hook nil "Normal hook to be run at the end of `tramp-handle-write-region'.") -;; CCC grok APPEND, LOCKNAME +;; CCC grok LOCKNAME (defun tramp-handle-write-region (start end filename &optional append visit lockname confirm) "Like `write-region' for Tramp files." (setq filename (expand-file-name filename)) (with-parsed-tramp-file-name filename nil - (unless (null append) - (tramp-error - v 'file-error "Cannot append to file using Tramp (`%s')" filename)) ;; Following part commented out because we don't know what to do about ;; file locking, and it does not appear to be a problem to ignore it. ;; Ange-ftp ignores it, too. @@ -4644,8 +4672,13 @@ ;; Write region into a tmp file. This isn't really ;; needed if we use an encoding function, but currently ;; we use it always because this makes the logic - ;; simpler. - (tmpfile (tramp-compat-make-temp-file filename))) + ;; simpler. If `append' is non-nil, we copy the file + ;; locally, and let the native `write-region' + ;; implementation do the job. + (tmpfile (if append + (file-local-copy filename) + (or tramp-temp-buffer-file-name + (tramp-compat-make-temp-file filename))))) ;; We say `no-message' here because we don't want the ;; visited file modtime data to be clobbered from the temp @@ -4659,6 +4692,7 @@ 'write-region (list start end tmpfile append 'no-message lockname confirm)) ((error quit) + (setq tramp-temp-buffer-file-name nil) (delete-file tmpfile) (signal (car err) (cdr err)))) @@ -4686,8 +4720,19 @@ (tramp-method-out-of-band-p v (- (or end (point-max)) (or start (point-min))))) (condition-case err - (rename-file tmpfile filename t) + (if (and (= (or end (point-max)) (point-max)) + (= (or start (point-min)) (point-min)) + (tramp-get-method-parameter + method 'tramp-copy-keep-tmpfile)) + (progn + ;; We keep the local file for performance + ;; reasons, useful for "rsync". + (setq tramp-temp-buffer-file-name tmpfile) + (copy-file tmpfile filename t)) + (setq tramp-temp-buffer-file-name nil) + (rename-file tmpfile filename t)) ((error quit) + (setq tramp-temp-buffer-file-name nil) (delete-file tmpfile) (signal (car err) (cdr err))))) @@ -5816,6 +5861,19 @@ (format "*tramp/%s %s@%s*" method user host) (format "*tramp/%s %s*" method host)))) +(defun tramp-delete-temp-file-function () + "Remove temporary files related to current buffer." + (when (stringp tramp-temp-buffer-file-name) + (condition-case nil + (delete-file tramp-temp-buffer-file-name) + (error nil)))) + +(add-hook 'kill-buffer-hook 'tramp-delete-temp-file-function) +(add-hook 'tramp-cache-unload-hook + (lambda () + (remove-hook 'kill-buffer-hook + 'tramp-delete-temp-file-function))) + (defun tramp-get-buffer (vec) "Get the connection buffer to be used for VEC." (or (get-buffer (tramp-buffer-name vec)) @@ -8069,14 +8127,11 @@ ;; * `vc-directory' does not work. It never displays any files, even ;; if it does show files when run locally. ;; * How to deal with MULE in `insert-file-contents' and `write-region'? -;; * Grok `append' parameter for `write-region'. ;; * Test remote ksh or bash for tilde expansion in `tramp-find-shell'? ;; * abbreviate-file-name ;; * Better error checking. At least whenever we see something ;; strange when doing zerop, we should kill the process and start ;; again. (Greg Stark) -;; * Provide a local cache of old versions of remote files for the rsync -;; transfer method to use. (Greg Stark) ;; * Remove unneeded parameters from methods. ;; * Make it work for different encodings, and for different file name ;; encodings, too. (Daniel Pittman)