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.