diff options
| author | Michael Albinus | 2011-11-16 22:32:46 +0100 |
|---|---|---|
| committer | Michael Albinus | 2011-11-16 22:32:46 +0100 |
| commit | d0c8fc8abb5891d11b17a0b97f6fce0b066bb6cc (patch) | |
| tree | a710044184b92118ecf6232ed337299c1ff7f11a | |
| parent | 9d0cfcd67ddcfb664cef507b76dd439b3b7de805 (diff) | |
| download | emacs-d0c8fc8abb5891d11b17a0b97f6fce0b066bb6cc.tar.gz emacs-d0c8fc8abb5891d11b17a0b97f6fce0b066bb6cc.zip | |
* net/tramp.el (tramp-handle-file-truename): Cache only the local
file name.
* net/tramp-cache.el (tramp-flush-file-property): Flush also
properties of linked files. (Bug#9879)
| -rw-r--r-- | lisp/ChangeLog | 8 | ||||
| -rw-r--r-- | lisp/net/tramp-cache.el | 5 | ||||
| -rw-r--r-- | lisp/net/tramp-sh.el | 204 |
3 files changed, 117 insertions, 100 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 65996aebfb1..bfa5a940a76 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog | |||
| @@ -1,3 +1,11 @@ | |||
| 1 | 2011-11-16 Michael Albinus <michael.albinus@gmx.de> | ||
| 2 | |||
| 3 | * net/tramp.el (tramp-handle-file-truename): Cache only the local | ||
| 4 | file name. | ||
| 5 | |||
| 6 | * net/tramp-cache.el (tramp-flush-file-property): Flush also | ||
| 7 | properties of linked files. (Bug#9879) | ||
| 8 | |||
| 1 | 2011-11-16 Juanma Barranquero <lekktu@gmail.com> | 9 | 2011-11-16 Juanma Barranquero <lekktu@gmail.com> |
| 2 | 10 | ||
| 3 | * menu-bar.el (menu-bar-file-menu): | 11 | * menu-bar.el (menu-bar-file-menu): |
diff --git a/lisp/net/tramp-cache.el b/lisp/net/tramp-cache.el index b35ca3bbd18..56087a3aef6 100644 --- a/lisp/net/tramp-cache.el +++ b/lisp/net/tramp-cache.el | |||
| @@ -162,6 +162,11 @@ FILE must be a local file name on a connection identified via VEC." | |||
| 162 | ;;;###tramp-autoload | 162 | ;;;###tramp-autoload |
| 163 | (defun tramp-flush-file-property (vec file) | 163 | (defun tramp-flush-file-property (vec file) |
| 164 | "Remove all properties of FILE in the cache context of VEC." | 164 | "Remove all properties of FILE in the cache context of VEC." |
| 165 | ;; Remove file property of symlinks. | ||
| 166 | (let ((truename (tramp-get-file-property vec file "file-truename" nil))) | ||
| 167 | (when (and (stringp truename) | ||
| 168 | (not (string-equal file truename))) | ||
| 169 | (tramp-flush-file-property vec truename))) | ||
| 165 | ;; Unify localname. | 170 | ;; Unify localname. |
| 166 | (setq vec (copy-sequence vec)) | 171 | (setq vec (copy-sequence vec)) |
| 167 | (aset vec 3 (tramp-run-real-handler 'directory-file-name (list file))) | 172 | (aset vec 3 (tramp-run-real-handler 'directory-file-name (list file))) |
diff --git a/lisp/net/tramp-sh.el b/lisp/net/tramp-sh.el index 6cba1a5b7a6..1b00e81ef5d 100644 --- a/lisp/net/tramp-sh.el +++ b/lisp/net/tramp-sh.el | |||
| @@ -1058,106 +1058,110 @@ target of the symlink differ." | |||
| 1058 | (defun tramp-sh-handle-file-truename (filename &optional counter prev-dirs) | 1058 | (defun tramp-sh-handle-file-truename (filename &optional counter prev-dirs) |
| 1059 | "Like `file-truename' for Tramp files." | 1059 | "Like `file-truename' for Tramp files." |
| 1060 | (with-parsed-tramp-file-name (expand-file-name filename) nil | 1060 | (with-parsed-tramp-file-name (expand-file-name filename) nil |
| 1061 | (with-file-property v localname "file-truename" | 1061 | (tramp-make-tramp-file-name method user host |
| 1062 | (let ((result nil)) ; result steps in reverse order | 1062 | (with-file-property v localname "file-truename" |
| 1063 | (tramp-message v 4 "Finding true name for `%s'" filename) | 1063 | (let ((result nil)) ; result steps in reverse order |
| 1064 | (cond | 1064 | (tramp-message v 4 "Finding true name for `%s'" filename) |
| 1065 | ;; Use GNU readlink --canonicalize-missing where available. | 1065 | (cond |
| 1066 | ((tramp-get-remote-readlink v) | 1066 | ;; Use GNU readlink --canonicalize-missing where available. |
| 1067 | (setq result | 1067 | ((tramp-get-remote-readlink v) |
| 1068 | (tramp-send-command-and-read | 1068 | (setq result |
| 1069 | v | 1069 | (tramp-send-command-and-read |
| 1070 | (format "echo \"\\\"`%s --canonicalize-missing %s`\\\"\"" | 1070 | v |
| 1071 | (tramp-get-remote-readlink v) | 1071 | (format "echo \"\\\"`%s --canonicalize-missing %s`\\\"\"" |
| 1072 | (tramp-shell-quote-argument localname))))) | 1072 | (tramp-get-remote-readlink v) |
| 1073 | 1073 | (tramp-shell-quote-argument localname))))) | |
| 1074 | ;; Use Perl implementation. | 1074 | |
| 1075 | ((and (tramp-get-remote-perl v) | 1075 | ;; Use Perl implementation. |
| 1076 | (tramp-get-connection-property v "perl-file-spec" nil) | 1076 | ((and (tramp-get-remote-perl v) |
| 1077 | (tramp-get-connection-property v "perl-cwd-realpath" nil)) | 1077 | (tramp-get-connection-property v "perl-file-spec" nil) |
| 1078 | (tramp-maybe-send-script | 1078 | (tramp-get-connection-property v "perl-cwd-realpath" nil)) |
| 1079 | v tramp-perl-file-truename "tramp_perl_file_truename") | 1079 | (tramp-maybe-send-script |
| 1080 | (setq result | 1080 | v tramp-perl-file-truename "tramp_perl_file_truename") |
| 1081 | (tramp-send-command-and-read | 1081 | (setq result |
| 1082 | v | 1082 | (tramp-send-command-and-read |
| 1083 | (format "tramp_perl_file_truename %s" | 1083 | v |
| 1084 | (tramp-shell-quote-argument localname))))) | 1084 | (format "tramp_perl_file_truename %s" |
| 1085 | 1085 | (tramp-shell-quote-argument localname))))) | |
| 1086 | ;; Do it yourself. We bind `directory-sep-char' here for | 1086 | |
| 1087 | ;; XEmacs on Windows, which would otherwise use backslash. | 1087 | ;; Do it yourself. We bind `directory-sep-char' here for |
| 1088 | (t (let* ((directory-sep-char ?/) | 1088 | ;; XEmacs on Windows, which would otherwise use backslash. |
| 1089 | (steps (tramp-compat-split-string localname "/")) | 1089 | (t (let* ((directory-sep-char ?/) |
| 1090 | (localnamedir (tramp-run-real-handler | 1090 | (steps (tramp-compat-split-string localname "/")) |
| 1091 | 'file-name-as-directory (list localname))) | 1091 | (localnamedir (tramp-run-real-handler |
| 1092 | (is-dir (string= localname localnamedir)) | 1092 | 'file-name-as-directory (list localname))) |
| 1093 | (thisstep nil) | 1093 | (is-dir (string= localname localnamedir)) |
| 1094 | (numchase 0) | 1094 | (thisstep nil) |
| 1095 | ;; Don't make the following value larger than | 1095 | (numchase 0) |
| 1096 | ;; necessary. People expect an error message in a | 1096 | ;; Don't make the following value larger than |
| 1097 | ;; timely fashion when something is wrong; | 1097 | ;; necessary. People expect an error message in |
| 1098 | ;; otherwise they might think that Emacs is hung. | 1098 | ;; a timely fashion when something is wrong; |
| 1099 | ;; Of course, correctness has to come first. | 1099 | ;; otherwise they might think that Emacs is hung. |
| 1100 | (numchase-limit 20) | 1100 | ;; Of course, correctness has to come first. |
| 1101 | symlink-target) | 1101 | (numchase-limit 20) |
| 1102 | (while (and steps (< numchase numchase-limit)) | 1102 | symlink-target) |
| 1103 | (setq thisstep (pop steps)) | 1103 | (while (and steps (< numchase numchase-limit)) |
| 1104 | (tramp-message | 1104 | (setq thisstep (pop steps)) |
| 1105 | v 5 "Check %s" | 1105 | (tramp-message |
| 1106 | (mapconcat 'identity | 1106 | v 5 "Check %s" |
| 1107 | (append '("") (reverse result) (list thisstep)) | 1107 | (mapconcat 'identity |
| 1108 | "/")) | 1108 | (append '("") (reverse result) (list thisstep)) |
| 1109 | (setq symlink-target | 1109 | "/")) |
| 1110 | (nth 0 (file-attributes | 1110 | (setq symlink-target |
| 1111 | (tramp-make-tramp-file-name | 1111 | (nth 0 (file-attributes |
| 1112 | method user host | 1112 | (tramp-make-tramp-file-name |
| 1113 | (mapconcat 'identity | 1113 | method user host |
| 1114 | (append '("") | 1114 | (mapconcat 'identity |
| 1115 | (reverse result) | 1115 | (append '("") |
| 1116 | (list thisstep)) | 1116 | (reverse result) |
| 1117 | "/"))))) | 1117 | (list thisstep)) |
| 1118 | (cond ((string= "." thisstep) | 1118 | "/"))))) |
| 1119 | (tramp-message v 5 "Ignoring step `.'")) | 1119 | (cond ((string= "." thisstep) |
| 1120 | ((string= ".." thisstep) | 1120 | (tramp-message v 5 "Ignoring step `.'")) |
| 1121 | (tramp-message v 5 "Processing step `..'") | 1121 | ((string= ".." thisstep) |
| 1122 | (pop result)) | 1122 | (tramp-message v 5 "Processing step `..'") |
| 1123 | ((stringp symlink-target) | 1123 | (pop result)) |
| 1124 | ;; It's a symlink, follow it. | 1124 | ((stringp symlink-target) |
| 1125 | (tramp-message v 5 "Follow symlink to %s" symlink-target) | 1125 | ;; It's a symlink, follow it. |
| 1126 | (setq numchase (1+ numchase)) | 1126 | (tramp-message |
| 1127 | (when (file-name-absolute-p symlink-target) | 1127 | v 5 "Follow symlink to %s" symlink-target) |
| 1128 | (setq result nil)) | 1128 | (setq numchase (1+ numchase)) |
| 1129 | ;; If the symlink was absolute, we'll get a string like | 1129 | (when (file-name-absolute-p symlink-target) |
| 1130 | ;; "/user@host:/some/target"; extract the | 1130 | (setq result nil)) |
| 1131 | ;; "/some/target" part from it. | 1131 | ;; If the symlink was absolute, we'll get a |
| 1132 | (when (tramp-tramp-file-p symlink-target) | 1132 | ;; string like "/user@host:/some/target"; |
| 1133 | (unless (tramp-equal-remote filename symlink-target) | 1133 | ;; extract the "/some/target" part from it. |
| 1134 | (tramp-error | 1134 | (when (tramp-tramp-file-p symlink-target) |
| 1135 | v 'file-error | 1135 | (unless (tramp-equal-remote filename symlink-target) |
| 1136 | "Symlink target `%s' on wrong host" symlink-target)) | 1136 | (tramp-error |
| 1137 | (setq symlink-target localname)) | 1137 | v 'file-error |
| 1138 | (setq steps | 1138 | "Symlink target `%s' on wrong host" |
| 1139 | (append (tramp-compat-split-string | 1139 | symlink-target)) |
| 1140 | symlink-target "/") | 1140 | (setq symlink-target localname)) |
| 1141 | steps))) | 1141 | (setq steps |
| 1142 | (t | 1142 | (append (tramp-compat-split-string |
| 1143 | ;; It's a file. | 1143 | symlink-target "/") |
| 1144 | (setq result (cons thisstep result))))) | 1144 | steps))) |
| 1145 | (when (>= numchase numchase-limit) | 1145 | (t |
| 1146 | (tramp-error | 1146 | ;; It's a file. |
| 1147 | v 'file-error | 1147 | (setq result (cons thisstep result))))) |
| 1148 | "Maximum number (%d) of symlinks exceeded" numchase-limit)) | 1148 | (when (>= numchase numchase-limit) |
| 1149 | (setq result (reverse result)) | 1149 | (tramp-error |
| 1150 | ;; Combine list to form string. | 1150 | v 'file-error |
| 1151 | (setq result | 1151 | "Maximum number (%d) of symlinks exceeded" numchase-limit)) |
| 1152 | (if result | 1152 | (setq result (reverse result)) |
| 1153 | (mapconcat 'identity (cons "" result) "/") | 1153 | ;; Combine list to form string. |
| 1154 | "/")) | 1154 | (setq result |
| 1155 | (when (and is-dir (or (string= "" result) | 1155 | (if result |
| 1156 | (not (string= (substring result -1) "/")))) | 1156 | (mapconcat 'identity (cons "" result) "/") |
| 1157 | (setq result (concat result "/")))))) | 1157 | "/")) |
| 1158 | 1158 | (when (and is-dir | |
| 1159 | (tramp-message v 4 "True name of `%s' is `%s'" filename result) | 1159 | (or (string= "" result) |
| 1160 | (tramp-make-tramp-file-name method user host result))))) | 1160 | (not (string= (substring result -1) "/")))) |
| 1161 | (setq result (concat result "/")))))) | ||
| 1162 | |||
| 1163 | (tramp-message v 4 "True name of `%s' is `%s'" localname result) | ||
| 1164 | result))))) | ||
| 1161 | 1165 | ||
| 1162 | ;; Basic functions. | 1166 | ;; Basic functions. |
| 1163 | 1167 | ||