[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
problem of `tramp-handle-file-local-copy' and inline transfer compressin
From: |
Toru TSUNEYOSHI |
Subject: |
problem of `tramp-handle-file-local-copy' and inline transfer compressing |
Date: |
Thu, 22 Apr 2010 19:29:48 +0900 (JST) |
Hello, everyone.
I am one of tramp users. Tramp is very, very useful. Thanks, developers.
Well, while I use tramp, I met a problem. It is that tramp cannot deal
with file whose name extension is "gz" (maybe "bz2", "zip", and so on)
in the case of using inline transfer. I found that
`tramp-handle-file-local-copy' had the problem.
So I made the patch for it. Please check
"tramp.el.jka-compr-inhibit.diff". If it is valid, please apply it.
(tramp-version => "2.1.15" on Emacs 23.1)
And, I use `plink' usually. As you know, inline transfer of `plink' is
very, very slow. (Of course, I sometimes use `pscp' if file size is
large.)
So I made `tramp-handle-file-local-copy' and `tramp-handle-write-region'
enable inline transfer compressing. The speed is approximately 1.5 - 4
times than the original. (In some cases, approximately 10 times.)
Please check "tramp.el.jka-compr-inhibit+compress.diff".
If it is valid, please apply it.
(Sorry, please correct variable/function name if it is not proper.)
--- tramp.el.original 2009-07-08 22:22:51.000000000 +0900
+++ tramp.el 2010-04-22 11:24:19.918277500 +0900
@@ -4095,13 +4095,15 @@
v 5 "Decoding remote file %s with function %s..."
filename loc-dec)
(funcall loc-dec (point-min) (point-max))
- (let ((coding-system-for-write 'binary))
+ (let ((coding-system-for-write 'binary)
+ (jka-compr-inhibit t))
(write-region (point-min) (point-max) tmpfile)))
;; If tramp-decoding-function is not defined for this
;; method, we invoke tramp-decoding-command instead.
(let ((tmpfile2 (tramp-compat-make-temp-file filename)))
- (let ((coding-system-for-write 'binary))
+ (let ((coding-system-for-write 'binary)
+ (jka-compr-inhibit t))
(write-region (point-min) (point-max) tmpfile2))
(tramp-message
v 5 "Decoding remote file %s with command %s..."
--- tramp.el.original 2009-07-08 22:22:51.000000000 +0900
+++ tramp.el 2010-04-22 11:38:30.907395300 +0900
@@ -263,6 +263,13 @@
:group 'tramp
:type 'string)
+(defcustom tramp-inline-transfer-compress-start-size 4096
+ "*The minimum size of compressing where inline transfer.
+When inline transfer, compress transfered data of file
+whose size is this value or above (up to `tramp-copy-size-limit')."
+ :group 'tramp
+ :type 'integer)
+
(defcustom tramp-copy-size-limit 10240
"*The maximum file size where inline copying is preferred over an
out-of-the-band copy."
:group 'tramp
@@ -4062,24 +4069,31 @@
(let ((rem-enc (tramp-get-remote-coding v "remote-encoding"))
(loc-dec (tramp-get-local-coding v "local-decoding"))
- (tmpfile (tramp-compat-make-temp-file filename)))
+ (tmpfile (tramp-compat-make-temp-file filename))
+ (filesize (nth 7 (file-attributes filename)))
+ compress decompress)
(condition-case err
(cond
;; `copy-file' handles direct copy and out-of-band methods.
((or (tramp-local-host-p v)
(and (tramp-method-out-of-band-p v)
- (> (nth 7 (file-attributes filename))
+ (> filesize
tramp-copy-size-limit)))
(copy-file filename tmpfile t t))
;; Use inline encoding for file transfer.
(rem-enc
+ (if (<= tramp-inline-transfer-compress-start-size filesize)
+ (setq compress (tramp-get-inline-transfer-compress v
"inline-transfer-compress")
+ decompress (tramp-get-inline-transfer-compress v
"inline-transfer-decompress")))
(save-excursion
(tramp-message v 5 "Encoding remote file %s..." filename)
(tramp-barf-unless-okay
v
- (format "%s < %s" rem-enc (tramp-shell-quote-argument localname))
+ (if compress
+ (format "%s < %s | %s" compress (tramp-shell-quote-argument
localname) rem-enc)
+ (format "%s < %s" rem-enc (tramp-shell-quote-argument
localname)))
"Encoding remote file failed")
(tramp-message v 5 "Encoding remote file %s...done" filename)
@@ -4095,19 +4109,46 @@
v 5 "Decoding remote file %s with function %s..."
filename loc-dec)
(funcall loc-dec (point-min) (point-max))
- (let ((coding-system-for-write 'binary))
+ (let ((coding-system-for-write 'binary)
+ (jka-compr-inhibit t))
+ (when decompress
+ (tramp-message
+ v 5 "Decompress remote file %s with command `%s'..."
+ filename decompress)
+ (call-process-region (point-min) (point-max)
+ tramp-encoding-shell
+ t t nil
+ tramp-encoding-command-switch
+ decompress))
(write-region (point-min) (point-max) tmpfile)))
;; If tramp-decoding-function is not defined for this
;; method, we invoke tramp-decoding-command instead.
(let ((tmpfile2 (tramp-compat-make-temp-file filename)))
- (let ((coding-system-for-write 'binary))
+ (let ((coding-system-for-write 'binary)
+ (jka-compr-inhibit t))
(write-region (point-min) (point-max) tmpfile2))
(tramp-message
v 5 "Decoding remote file %s with command %s..."
filename loc-dec)
(unwind-protect
- (tramp-call-local-coding-command loc-dec tmpfile2 tmpfile)
+ (progn
+ (tramp-call-local-coding-command loc-dec tmpfile2
tmpfile)
+ (if decompress
+ (with-temp-buffer
+ (set-buffer-multibyte nil)
+ (insert-file-contents-literally tmpfile)
+ (let ((coding-system-for-write 'binary)
+ (jka-compr-inhibit t))
+ (tramp-message
+ v 5 "Decompress remote file %s with command
`%s'..."
+ filename decompress)
+ (call-process-region (point-min) (point-max)
+ tramp-encoding-shell
+ t t nil
+
tramp-encoding-command-switch
+ decompress)
+ (write-region (point-min) (point-max)
tmpfile)))))
(delete-file tmpfile2))))
(tramp-message v 5 "Decoding remote file %s...done" filename)
@@ -4389,7 +4430,9 @@
;; 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)))
+ (tmpfile (tramp-compat-make-temp-file filename))
+ filesize
+ compress decompress)
;; We say `no-message' here because we don't want the
;; visited file modtime data to be clobbered from the temp
@@ -4424,11 +4467,12 @@
;; specified. However, if the method _also_ specifies an
;; encoding function, then that is used for encoding the
;; contents of the tmp file.
+ (setq filesize (nth 7 (file-attributes tmpfile)))
(cond
;; `rename-file' handles direct copy and out-of-band methods.
((or (tramp-local-host-p v)
(and (tramp-method-out-of-band-p v)
- (> (- (or end (point-max)) (or start (point-min)))
+ (> filesize
tramp-copy-size-limit)))
(condition-case err
(rename-file tmpfile filename t)
@@ -4438,6 +4482,9 @@
;; Use inline file transfer.
(rem-dec
+ (if (<= tramp-inline-transfer-compress-start-size filesize)
+ (setq compress (tramp-get-inline-transfer-compress v
"inline-transfer-compress")
+ decompress (tramp-get-inline-transfer-compress v
"inline-transfer-decompress")))
;; Encode tmpfile.
(tramp-message v 5 "Encoding region...")
(unwind-protect
@@ -4461,6 +4508,15 @@
;; a tmp file anyway.
(let ((default-directory
(tramp-compat-temporary-file-directory)))
+ (when compress
+ (tramp-message
+ v 5 "Compress local file %s with command `%s'..."
+ filename compress)
+ (call-process-region (point-min) (point-max)
+ tramp-encoding-shell
+ t t nil
+ tramp-encoding-command-switch
+ compress))
(funcall loc-enc (point-min) (point-max))))
(tramp-message
@@ -4481,11 +4537,18 @@
v 5 "Decoding region into remote file %s..." filename)
(tramp-send-command
v
- (format
- "%s >%s <<'EOF'\n%sEOF"
- rem-dec
- (tramp-shell-quote-argument localname)
- (buffer-string)))
+ (if decompress
+ (format
+ "(%s | %s >%s) <<'EOF'\n%sEOF"
+ rem-dec
+ decompress
+ (tramp-shell-quote-argument localname)
+ (buffer-string))
+ (format
+ "%s >%s <<'EOF'\n%sEOF"
+ rem-dec
+ (tramp-shell-quote-argument localname)
+ (buffer-string))))
(tramp-barf-unless-okay
v nil
"Couldn't write region to `%s', decode using `%s' failed"
@@ -4510,11 +4573,17 @@
(buffer-string)
(with-current-buffer (tramp-get-buffer v)
(buffer-string))))
- (tramp-error
- v 'file-error
- (concat "Couldn't write region to `%s',"
- " decode using `%s' failed")
- filename rem-dec)))
+ (if decompress
+ (tramp-error
+ v 'file-error
+ (concat "Couldn't write region to `%s',"
+ " decode using `%s' and `%s' failed")
+ filename rem-dec decompress)
+ (tramp-error
+ v 'file-error
+ (concat "Couldn't write region to `%s',"
+ " decode using `%s' failed")
+ filename rem-dec))))
(tramp-message
v 5 "Decoding region into remote file %s...done" filename)
(tramp-flush-file-property v localname))
@@ -6312,6 +6381,62 @@
(tramp-message vec 5 "Using remote decoding `%s'" rem-dec)
(tramp-set-connection-property vec "remote-decoding" rem-dec))))
+(defconst tramp-inline-transfer-compress-commands
+ '(("gzip" "gzip -d")
+ ("bzip2" "bzip2 -d")
+ ("compress" "compress -d"))
+ "List of compress commands for inline transfer.
+Each item is a list that looks like this:
+
+\(ENCODING DECODING).
+
+ENCODING or DECODING is a list that looks like this:
+
+\(\"executable program\")
+or
+\(\"executable program\" \"option\" ...) ")
+
+(defun tramp-find-inline-transfer-compress (vec)
+ "Find an inline transfer compress command that works.
+Goes through the list `tramp-inline-transfer-compress-commands'."
+ (save-excursion
+ (let ((commands tramp-inline-transfer-compress-commands)
+ (magic "xyzzy")
+ item compress decompress
+ found)
+ (while (and commands (not found))
+ (catch 'next
+ (setq item (pop commands)
+ compress (nth 0 item)
+ decompress (nth 1 item))
+ (tramp-message
+ vec 5 "Checking local inline transfer compress command `%s', `%s'
for sanity" compress decompress)
+ (unless (zerop (tramp-call-local-coding-command
+ (format "echo %s | %s | %s"
+ magic compress decompress) nil nil))
+ (throw 'next nil))
+ (tramp-message
+ vec 5 "Checking remote inline transfer compress command `%s', `%s'
for sanity" compress decompress)
+ (unless (zerop (tramp-send-command-and-check
+ vec
+ (format "echo %s | %s | %s"
+ magic compress decompress) t))
+ (throw 'next nil))
+ (setq found t)))
+
+ ;; Did we find something?
+ (if found
+ (progn
+ ;; Set connection properties.
+ (tramp-message vec 5 "Using inline transfer compress command `%s'"
compress)
+ (tramp-set-connection-property vec "inline-transfer-compress"
compress)
+ (tramp-message vec 5 "Using inline transfer decompress command
`%s'" decompress)
+ (tramp-set-connection-property vec "inline-transfer-decompress"
decompress))
+ ;; Set connection properties as checked (t).
+ (tramp-set-connection-property vec "inline-transfer-compress" t)
+ (tramp-set-connection-property vec "inline-transfer-decompress" t)
+ (tramp-message vec 2 "Couldn't find an inline transfer compress
command")))))
+
(defun tramp-call-local-coding-command (cmd input output)
"Call the local encoding or decoding command.
If CMD contains \"%s\", provide input file INPUT there in command.
@@ -7388,6 +7513,19 @@
(tramp-find-inline-encoding vec)
(tramp-get-connection-property vec prop nil))))
+(defun tramp-get-inline-transfer-compress (vec prop)
+ (let ((val (tramp-get-connection-property vec prop nil)))
+ (if (eq val t) ; already checked, and compress command not found
+ nil
+ (or
+ val
+ (progn
+ (tramp-find-inline-transfer-compress vec)
+ (setq val (tramp-get-inline-transfer-compress vec prop))
+ (if (eq val t) ; compress command not found
+ nil
+ val))))))
+
(defun tramp-get-method-parameter (method param)
"Return the method parameter PARAM.
If the `tramp-methods' entry does not exist, return NIL."
- problem of `tramp-handle-file-local-copy' and inline transfer compressing,
Toru TSUNEYOSHI <=
- Re: problem of `tramp-handle-file-local-copy' and inline transfer compressing, Michael Albinus, 2010/04/22
- Re: problem of `tramp-handle-file-local-copy' and inline transfer compressing, Toru TSUNEYOSHI, 2010/04/22
- Re: problem of `tramp-handle-file-local-copy' and inline transfer compressing, Michael Albinus, 2010/04/22
- Re: problem of `tramp-handle-file-local-copy' and inline transfer compressing, Toru TSUNEYOSHI, 2010/04/26
- Re: problem of `tramp-handle-file-local-copy' and inline transfer compressing, Michael Albinus, 2010/04/27
- Re: problem of `tramp-handle-file-local-copy' and inline transfer compressing, Toru TSUNEYOSHI, 2010/04/28
- Re: problem of `tramp-handle-file-local-copy' and inline transfer compressing, Michael Albinus, 2010/04/28
- Re: problem of `tramp-handle-file-local-copy' and inline transfer compressing, Toru TSUNEYOSHI, 2010/04/28
- Re: problem of `tramp-handle-file-local-copy' and inline transfer compressing, Michael Albinus, 2010/04/28
- Re: problem of `tramp-handle-file-local-copy' and inline transfer compressing, Toru TSUNEYOSHI, 2010/04/28