Mercurial > emacs
comparison lisp/net/tramp.el @ 85041:a42b8750a992
* net/tramp.el (tramp-make-temp-file): Move to tramp-compat.el.
(tramp-do-copy-or-rename-file-directly): Handle tmpfile only in
the cond clauses where needed.
(tramp-handle-write-region): Rearrange code for proper handling of
tmpfile.
* net/tramp-compat.el (tramp-compat-make-temp-file): New defsubst.
* net/tramp.el:
* net/tramp-fish.el:
* net/tramp-ftp.el:
* net/tramp-smb.el: Rename `tramp-make-temp-file' to
`tramp-compat-make-temp-file'.
author | Michael Albinus <michael.albinus@gmx.de> |
---|---|
date | Thu, 04 Oct 2007 20:09:32 +0000 |
parents | ef71cdab0d5c |
children | 4636000015c5 |
comparison
equal
deleted
inserted
replaced
85040:9aefbe205648 | 85041:a42b8750a992 |
---|---|
1972 (let ((,variable ,value)) | 1972 (let ((,variable ,value)) |
1973 ,@body))) | 1973 ,@body))) |
1974 (put 'tramp-let-maybe 'lisp-indent-function 2) | 1974 (put 'tramp-let-maybe 'lisp-indent-function 2) |
1975 (put 'tramp-let-maybe 'edebug-form-spec t) | 1975 (put 'tramp-let-maybe 'edebug-form-spec t) |
1976 | 1976 |
1977 (defsubst tramp-make-temp-file (filename) | |
1978 (concat | |
1979 (make-temp-name | |
1980 (expand-file-name | |
1981 tramp-temp-name-prefix (tramp-compat-temporary-file-directory))) | |
1982 (file-name-extension filename t))) | |
1983 | |
1984 (defsubst tramp-make-tramp-temp-file (vec) | 1977 (defsubst tramp-make-tramp-temp-file (vec) |
1985 (format | 1978 (format |
1986 "/tmp/%s%s" | 1979 "/tmp/%s%s" |
1987 tramp-temp-name-prefix | 1980 tramp-temp-name-prefix |
1988 (if (get-buffer-process (tramp-get-connection-buffer vec)) | 1981 (if (get-buffer-process (tramp-get-connection-buffer vec)) |
3069 op)))) | 3062 op)))) |
3070 (localname1 | 3063 (localname1 |
3071 (if t1 (tramp-handle-file-remote-p filename 'localname) filename)) | 3064 (if t1 (tramp-handle-file-remote-p filename 'localname) filename)) |
3072 (localname2 | 3065 (localname2 |
3073 (if t2 (tramp-handle-file-remote-p newname 'localname) newname)) | 3066 (if t2 (tramp-handle-file-remote-p newname 'localname) newname)) |
3074 (prefix (file-remote-p (if t1 filename newname))) | 3067 (prefix (file-remote-p (if t1 filename newname)))) |
3075 (tmpfile (tramp-make-temp-file localname1))) | |
3076 | 3068 |
3077 (cond | 3069 (cond |
3078 ;; Both files are on a remote host, with same user. | 3070 ;; Both files are on a remote host, with same user. |
3079 ((and t1 t2) | 3071 ((and t1 t2) |
3080 (tramp-send-command | 3072 (tramp-send-command |
3122 (tramp-get-local-gid 'integer))) | 3114 (tramp-get-local-gid 'integer))) |
3123 | 3115 |
3124 ;; We need a temporary file in between. | 3116 ;; We need a temporary file in between. |
3125 (t | 3117 (t |
3126 ;; Create the temporary file. | 3118 ;; Create the temporary file. |
3127 (cond | 3119 (let ((tmpfile (tramp-compat-make-temp-file localname1))) |
3128 (t1 | 3120 (cond |
3129 (tramp-send-command | 3121 (t1 |
3130 v (format | 3122 (tramp-send-command |
3131 "%s %s %s" cmd | 3123 v (format |
3132 (tramp-shell-quote-argument localname1) | 3124 "%s %s %s" cmd |
3133 (tramp-shell-quote-argument tmpfile))) | 3125 (tramp-shell-quote-argument localname1) |
3134 ;; We must change the ownership as remote user. | 3126 (tramp-shell-quote-argument tmpfile))) |
3135 (tramp-set-file-uid-gid | 3127 ;; We must change the ownership as remote user. |
3136 (concat prefix tmpfile) | 3128 (tramp-set-file-uid-gid |
3137 (tramp-get-local-uid 'integer) | 3129 (concat prefix tmpfile) |
3138 (tramp-get-local-gid 'integer))) | 3130 (tramp-get-local-uid 'integer) |
3139 (t2 | 3131 (tramp-get-local-gid 'integer))) |
3140 (if (eq op 'copy) | 3132 (t2 |
3141 (tramp-compat-copy-file | 3133 (if (eq op 'copy) |
3142 localname1 tmpfile ok-if-already-exists | 3134 (tramp-compat-copy-file |
3143 keep-date preserve-uid-gid) | 3135 localname1 tmpfile ok-if-already-exists |
3144 (rename-file localname1 tmpfile ok-if-already-exists)) | 3136 keep-date preserve-uid-gid) |
3145 ;; We must change the ownership as local user. | 3137 (rename-file localname1 tmpfile ok-if-already-exists)) |
3146 (tramp-set-file-uid-gid | 3138 ;; We must change the ownership as local user. |
3147 tmpfile | 3139 (tramp-set-file-uid-gid |
3148 (tramp-get-remote-uid v 'integer) | 3140 tmpfile |
3149 (tramp-get-remote-gid v 'integer)))) | 3141 (tramp-get-remote-uid v 'integer) |
3150 | 3142 (tramp-get-remote-gid v 'integer)))) |
3151 ;; Move the temporary file to its destination. | 3143 |
3152 (cond | 3144 ;; Move the temporary file to its destination. |
3153 (t2 | 3145 (cond |
3154 (tramp-send-command | 3146 (t2 |
3155 v (format | 3147 (tramp-send-command |
3156 "mv -f %s %s" | 3148 v (format |
3157 (tramp-shell-quote-argument tmpfile) | 3149 "mv -f %s %s" |
3158 (tramp-shell-quote-argument localname2)))) | 3150 (tramp-shell-quote-argument tmpfile) |
3159 (t1 | 3151 (tramp-shell-quote-argument localname2)))) |
3160 (rename-file tmpfile localname2 ok-if-already-exists)))))))) | 3152 (t1 |
3153 (rename-file tmpfile localname2 ok-if-already-exists))))))))) | |
3161 | 3154 |
3162 ;; Set the time and mode. Mask possible errors. | 3155 ;; Set the time and mode. Mask possible errors. |
3163 ;; Won't be applied for 'rename. | 3156 ;; Won't be applied for 'rename. |
3164 (condition-case nil | 3157 (condition-case nil |
3165 (when (and keep-date (not preserve-uid-gid)) | 3158 (when (and keep-date (not preserve-uid-gid)) |
3734 ret))) | 3727 ret))) |
3735 | 3728 |
3736 (defun tramp-handle-call-process-region | 3729 (defun tramp-handle-call-process-region |
3737 (start end program &optional delete buffer display &rest args) | 3730 (start end program &optional delete buffer display &rest args) |
3738 "Like `call-process-region' for Tramp files." | 3731 "Like `call-process-region' for Tramp files." |
3739 (let ((tmpfile (tramp-make-temp-file ""))) | 3732 (let ((tmpfile (tramp-compat-make-temp-file ""))) |
3740 (write-region start end tmpfile) | 3733 (write-region start end tmpfile) |
3741 (when delete (delete-region start end)) | 3734 (when delete (delete-region start end)) |
3742 (unwind-protect | 3735 (unwind-protect |
3743 (apply 'call-process program tmpfile buffer display args) | 3736 (apply 'call-process program tmpfile buffer display args) |
3744 (delete-file tmpfile)))) | 3737 (delete-file tmpfile)))) |
3796 "Like `file-local-copy' for Tramp files." | 3789 "Like `file-local-copy' for Tramp files." |
3797 | 3790 |
3798 (with-parsed-tramp-file-name filename nil | 3791 (with-parsed-tramp-file-name filename nil |
3799 (let ((rem-enc (tramp-get-remote-coding v "remote-encoding")) | 3792 (let ((rem-enc (tramp-get-remote-coding v "remote-encoding")) |
3800 (loc-dec (tramp-get-local-coding v "local-decoding")) | 3793 (loc-dec (tramp-get-local-coding v "local-decoding")) |
3801 (tmpfile (tramp-make-temp-file filename))) | 3794 (tmpfile (tramp-compat-make-temp-file filename))) |
3802 (unless (file-exists-p filename) | 3795 (unless (file-exists-p filename) |
3803 (tramp-error | 3796 (tramp-error |
3804 v 'file-error | 3797 v 'file-error |
3805 "Cannot make local copy of non-existing file `%s'" filename)) | 3798 "Cannot make local copy of non-existing file `%s'" filename)) |
3806 | 3799 |
3835 (funcall loc-dec (point-min) (point-max)) | 3828 (funcall loc-dec (point-min) (point-max)) |
3836 (let ((coding-system-for-write 'binary)) | 3829 (let ((coding-system-for-write 'binary)) |
3837 (write-region (point-min) (point-max) tmpfile)))) | 3830 (write-region (point-min) (point-max) tmpfile)))) |
3838 ;; If tramp-decoding-function is not defined for this | 3831 ;; If tramp-decoding-function is not defined for this |
3839 ;; method, we invoke tramp-decoding-command instead. | 3832 ;; method, we invoke tramp-decoding-command instead. |
3840 (let ((tmpfile2 (tramp-make-temp-file filename))) | 3833 (let ((tmpfile2 (tramp-compat-make-temp-file filename))) |
3841 (let ((coding-system-for-write 'binary)) | 3834 (let ((coding-system-for-write 'binary)) |
3842 (write-region (point-min) (point-max) tmpfile2)) | 3835 (write-region (point-min) (point-max) tmpfile2)) |
3843 (tramp-message | 3836 (tramp-message |
3844 v 5 "Decoding remote file %s with command %s..." | 3837 v 5 "Decoding remote file %s with command %s..." |
3845 filename loc-dec) | 3838 filename loc-dec) |
4053 ;; XEmacs takes a coding system as the seventh argument, not `confirm'. | 4046 ;; XEmacs takes a coding system as the seventh argument, not `confirm'. |
4054 (when (and (not (featurep 'xemacs)) confirm (file-exists-p filename)) | 4047 (when (and (not (featurep 'xemacs)) confirm (file-exists-p filename)) |
4055 (unless (y-or-n-p (format "File %s exists; overwrite anyway? " filename)) | 4048 (unless (y-or-n-p (format "File %s exists; overwrite anyway? " filename)) |
4056 (tramp-error v 'file-error "File not overwritten"))) | 4049 (tramp-error v 'file-error "File not overwritten"))) |
4057 | 4050 |
4058 (let ((rem-dec (tramp-get-remote-coding v "remote-decoding")) | 4051 (if (and (tramp-local-host-p v) |
4059 (loc-enc (tramp-get-local-coding v "local-encoding")) | 4052 (file-writable-p (file-name-directory localname))) |
4060 (modes (save-excursion (file-modes filename))) | 4053 ;; Short track: if we are on the local host, we can run directly. |
4061 ;; We use this to save the value of `last-coding-system-used' | 4054 (if confirm |
4062 ;; after writing the tmp file. At the end of the function, | 4055 (write-region |
4063 ;; we set `last-coding-system-used' to this saved value. | 4056 start end localname append 'no-message lockname confirm) |
4064 ;; This way, any intermediary coding systems used while | 4057 (write-region start end localname append 'no-message lockname)) |
4065 ;; talking to the remote shell or suchlike won't hose this | 4058 |
4066 ;; variable. This approach was snarfed from ange-ftp.el. | 4059 (let ((rem-dec (tramp-get-remote-coding v "remote-decoding")) |
4067 coding-system-used | 4060 (loc-enc (tramp-get-local-coding v "local-encoding")) |
4068 ;; Write region into a tmp file. This isn't really needed if we | 4061 (modes (save-excursion (file-modes filename))) |
4069 ;; use an encoding function, but currently we use it always | 4062 ;; We use this to save the value of `last-coding-system-used' |
4070 ;; because this makes the logic simpler. | 4063 ;; after writing the tmp file. At the end of the function, |
4071 (tmpfile (tramp-make-temp-file filename))) | 4064 ;; we set `last-coding-system-used' to this saved value. |
4072 | 4065 ;; This way, any intermediary coding systems used while |
4073 (if (and (tramp-local-host-p v) | 4066 ;; talking to the remote shell or suchlike won't hose this |
4074 (file-writable-p (file-name-directory localname))) | 4067 ;; variable. This approach was snarfed from ange-ftp.el. |
4075 ;; Short track: if we are on the local host, we can run directly. | 4068 coding-system-used |
4076 (if confirm | 4069 ;; Write region into a tmp file. This isn't really needed if we |
4077 (write-region | 4070 ;; use an encoding function, but currently we use it always |
4078 start end localname append 'no-message lockname confirm) | 4071 ;; because this makes the logic simpler. |
4079 (write-region start end localname append 'no-message lockname)) | 4072 (tmpfile (tramp-compat-make-temp-file filename))) |
4080 | 4073 |
4081 ;; We say `no-message' here because we don't want the visited file | 4074 ;; We say `no-message' here because we don't want the visited file |
4082 ;; modtime data to be clobbered from the temp file. We call | 4075 ;; modtime data to be clobbered from the temp file. We call |
4083 ;; `set-visited-file-modtime' ourselves later on. | 4076 ;; `set-visited-file-modtime' ourselves later on. |
4084 (tramp-run-real-handler | 4077 (tramp-run-real-handler |
4199 (t | 4192 (t |
4200 (tramp-error | 4193 (tramp-error |
4201 v 'file-error | 4194 v 'file-error |
4202 (concat "Method `%s' should specify both encoding and " | 4195 (concat "Method `%s' should specify both encoding and " |
4203 "decoding command or an rcp program") | 4196 "decoding command or an rcp program") |
4204 method)))) | 4197 method))) |
4205 | 4198 |
4199 ;; Make `last-coding-system-used' have the right value. | |
4200 (when coding-system-used | |
4201 (set 'last-coding-system-used coding-system-used))) | |
4202 | |
4203 ;; Set file modification time. | |
4206 (when (or (eq visit t) (stringp visit)) | 4204 (when (or (eq visit t) (stringp visit)) |
4207 (set-visited-file-modtime | 4205 (set-visited-file-modtime |
4208 ;; We must pass modtime explicitely, because filename can be different | 4206 ;; We must pass modtime explicitely, because filename can be different |
4209 ;; from (buffer-file-name), f.e. if `file-precious-flag' is set. | 4207 ;; from (buffer-file-name), f.e. if `file-precious-flag' is set. |
4210 (nth 5 (file-attributes filename)))) | 4208 (nth 5 (file-attributes filename)))) |
4211 ;; Set the ownership. | 4209 ;; Set the ownership. |
4212 (tramp-set-file-uid-gid filename) | 4210 (tramp-set-file-uid-gid filename) |
4213 ;; Make `last-coding-system-used' have the right value. | |
4214 (when coding-system-used | |
4215 (set 'last-coding-system-used coding-system-used)) | |
4216 (when (or (eq visit t) (null visit) (stringp visit)) | 4211 (when (or (eq visit t) (null visit) (stringp visit)) |
4217 (tramp-message v 0 "Wrote %s" filename)) | 4212 (tramp-message v 0 "Wrote %s" filename)) |
4218 (run-hooks 'tramp-handle-write-region-hook)))) | 4213 (run-hooks 'tramp-handle-write-region-hook)))) |
4219 | 4214 |
4220 ;;;###autoload | 4215 ;;;###autoload |
7556 ;; * Don't search for perl5 and perl. Instead, only search for perl and | 7551 ;; * Don't search for perl5 and perl. Instead, only search for perl and |
7557 ;; then look if it's the right version (with `perl -v'). | 7552 ;; then look if it's the right version (with `perl -v'). |
7558 ;; * When editing a remote CVS controlled file as a different user, VC | 7553 ;; * When editing a remote CVS controlled file as a different user, VC |
7559 ;; gets confused about the file locking status. Try to find out why | 7554 ;; gets confused about the file locking status. Try to find out why |
7560 ;; the workaround doesn't work. | 7555 ;; the workaround doesn't work. |
7561 ;; * Change `copy-file' to grok the case where the filename handler | |
7562 ;; for the source and the target file are different. Right now, | |
7563 ;; it looks at the source file and then calls that handler, if | |
7564 ;; there is one. But since ange-ftp, for instance, does not know | |
7565 ;; about Tramp, it does not do the right thing if the target file | |
7566 ;; name is a Tramp name. | |
7567 ;; * Username and hostname completion. | 7556 ;; * Username and hostname completion. |
7568 ;; ** Try to avoid usage of `last-input-event' in `tramp-completion-mode-p'. | 7557 ;; ** Try to avoid usage of `last-input-event' in `tramp-completion-mode-p'. |
7569 ;; ** Unify `tramp-parse-{rhosts,shosts,sconfig,hosts,passwd,netrc}'. | 7558 ;; ** Unify `tramp-parse-{rhosts,shosts,sconfig,hosts,passwd,netrc}'. |
7570 ;; Code is nearly identical. | 7559 ;; Code is nearly identical. |
7571 ;; * Allow out-of-band methods as _last_ multi-hop. | 7560 ;; * Allow out-of-band methods as _last_ multi-hop. |