diff options
| author | Michael Albinus | 2015-08-24 14:26:57 +0200 |
|---|---|---|
| committer | Michael Albinus | 2015-08-24 14:26:57 +0200 |
| commit | 7eab29d251b893d5b7f87f1801706a86043fa428 (patch) | |
| tree | 377da59be89d2405db55f450b864472f6cb86f0e | |
| parent | 1c6bdf18c0f2116edef7f7195ca5ed7a55a05e73 (diff) | |
| download | emacs-7eab29d251b893d5b7f87f1801706a86043fa428.tar.gz emacs-7eab29d251b893d5b7f87f1801706a86043fa428.zip | |
* lisp/net/tramp-sh.el (tramp-stat-marker, tramp-stat-quoted-marker):
New defconsts.
(tramp-do-file-attributes-with-stat)
(tramp-do-directory-files-and-attributes-with-stat): Use them.
(tramp-convert-file-attributes): Remove double slashes in symlinks.
* test/automated/tramp-tests.el (tramp-test18-file-attributes):
Handle symlinks with "//" in the file name.
| -rw-r--r-- | lisp/net/tramp-sh.el | 62 | ||||
| -rw-r--r-- | test/automated/tramp-tests.el | 33 |
2 files changed, 72 insertions, 23 deletions
diff --git a/lisp/net/tramp-sh.el b/lisp/net/tramp-sh.el index 49d4c4a8c31..90b84b27950 100644 --- a/lisp/net/tramp-sh.el +++ b/lisp/net/tramp-sh.el | |||
| @@ -873,6 +873,12 @@ Escape sequence %s is replaced with name of Perl binary.") | |||
| 873 | "Perl program to use for decoding a file. | 873 | "Perl program to use for decoding a file. |
| 874 | Escape sequence %s is replaced with name of Perl binary.") | 874 | Escape sequence %s is replaced with name of Perl binary.") |
| 875 | 875 | ||
| 876 | (defconst tramp-stat-marker "/////" | ||
| 877 | "Marker in stat commands for file attributes.") | ||
| 878 | |||
| 879 | (defconst tramp-stat-quoted-marker "\\/\\/\\/\\/\\/" | ||
| 880 | "Quoted marker in stat commands for file attributes.") | ||
| 881 | |||
| 876 | (defconst tramp-vc-registered-read-file-names | 882 | (defconst tramp-vc-registered-read-file-names |
| 877 | "echo \"(\" | 883 | "echo \"(\" |
| 878 | while read file; do | 884 | while read file; do |
| @@ -1304,19 +1310,25 @@ target of the symlink differ." | |||
| 1304 | (concat | 1310 | (concat |
| 1305 | ;; On Opsware, pdksh (which is the true name of ksh there) | 1311 | ;; On Opsware, pdksh (which is the true name of ksh there) |
| 1306 | ;; doesn't parse correctly the sequence "((". Therefore, we add | 1312 | ;; doesn't parse correctly the sequence "((". Therefore, we add |
| 1307 | ;; a space. Apostrophes in the stat output are masked as "//", | 1313 | ;; a space. Apostrophes in the stat output are masked as |
| 1308 | ;; in order to make a proper shell escape of them in file names. | 1314 | ;; `tramp-stat-marker', in order to make a proper shell escape of |
| 1315 | ;; them in file names. | ||
| 1309 | "( (%s %s || %s -h %s) && (%s -c " | 1316 | "( (%s %s || %s -h %s) && (%s -c " |
| 1310 | "'((//%%N//) %%h %s %s %%Xe0 %%Ye0 %%Ze0 %%se0 //%%A// t %%ie0 -1)' " | 1317 | "'((%s%%N%s) %%h %s %s %%Xe0 %%Ye0 %%Ze0 %%se0 %s%%A%s t %%ie0 -1)' " |
| 1311 | "%s | sed -e 's/\"/\\\\\"/g' -e 's/\\/\\//\"/g') || echo nil)") | 1318 | "%s | sed -e 's/\"/\\\\\"/g' -e 's/%s/\"/g') || echo nil)") |
| 1312 | (tramp-get-file-exists-command vec) | 1319 | (tramp-get-file-exists-command vec) |
| 1313 | (tramp-shell-quote-argument localname) | 1320 | (tramp-shell-quote-argument localname) |
| 1314 | (tramp-get-test-command vec) | 1321 | (tramp-get-test-command vec) |
| 1315 | (tramp-shell-quote-argument localname) | 1322 | (tramp-shell-quote-argument localname) |
| 1316 | (tramp-get-remote-stat vec) | 1323 | (tramp-get-remote-stat vec) |
| 1317 | (if (eq id-format 'integer) "%ue0" "//%U//") | 1324 | tramp-stat-marker tramp-stat-marker |
| 1318 | (if (eq id-format 'integer) "%ge0" "//%G//") | 1325 | (if (eq id-format 'integer) |
| 1319 | (tramp-shell-quote-argument localname)))) | 1326 | "%ue0" (concat tramp-stat-marker "%U" tramp-stat-marker)) |
| 1327 | (if (eq id-format 'integer) | ||
| 1328 | "%ge0" (concat tramp-stat-marker "%G" tramp-stat-marker)) | ||
| 1329 | tramp-stat-marker tramp-stat-marker | ||
| 1330 | (tramp-shell-quote-argument localname) | ||
| 1331 | tramp-stat-quoted-marker))) | ||
| 1320 | 1332 | ||
| 1321 | (defun tramp-sh-handle-set-visited-file-modtime (&optional time-list) | 1333 | (defun tramp-sh-handle-set-visited-file-modtime (&optional time-list) |
| 1322 | "Like `set-visited-file-modtime' for Tramp files." | 1334 | "Like `set-visited-file-modtime' for Tramp files." |
| @@ -1747,12 +1759,12 @@ be non-negative integers." | |||
| 1747 | ;; We must care about file names with spaces, or starting with | 1759 | ;; We must care about file names with spaces, or starting with |
| 1748 | ;; "-"; this would confuse xargs. "ls -aQ" might be a solution, | 1760 | ;; "-"; this would confuse xargs. "ls -aQ" might be a solution, |
| 1749 | ;; but it does not work on all remote systems. Apostrophes in | 1761 | ;; but it does not work on all remote systems. Apostrophes in |
| 1750 | ;; the stat output are masked as "//", in order to make a proper | 1762 | ;; the stat output are masked as `tramp-stat-marker', in order to |
| 1751 | ;; shell escape of them in file names. | 1763 | ;; make a proper shell escape of them in file names. |
| 1752 | "cd %s && echo \"(\"; (%s %s -a | " | 1764 | "cd %s && echo \"(\"; (%s %s -a | " |
| 1753 | "xargs %s -c " | 1765 | "xargs %s -c " |
| 1754 | "'(//%%n// (//%%N//) %%h %s %s %%Xe0 %%Ye0 %%Ze0 %%se0 //%%A// t %%ie0 -1)' " | 1766 | "'(%s%%n%s (%s%%N%s) %%h %s %s %%Xe0 %%Ye0 %%Ze0 %%se0 %s%%A%s t %%ie0 -1)' " |
| 1755 | "-- 2>/dev/null | sed -e 's/\"/\\\\\"/g' -e 's/\\/\\//\"/g'); echo \")\"") | 1767 | "-- 2>/dev/null | sed -e 's/\"/\\\\\"/g' -e 's/%s/\"/g'); echo \")\"") |
| 1756 | (tramp-shell-quote-argument localname) | 1768 | (tramp-shell-quote-argument localname) |
| 1757 | (tramp-get-ls-command vec) | 1769 | (tramp-get-ls-command vec) |
| 1758 | ;; On systems which have no quoting style, file names with | 1770 | ;; On systems which have no quoting style, file names with |
| @@ -1760,8 +1772,14 @@ be non-negative integers." | |||
| 1760 | (if (tramp-get-ls-command-with-quoting-style vec) | 1772 | (if (tramp-get-ls-command-with-quoting-style vec) |
| 1761 | "--quoting-style=shell" "") | 1773 | "--quoting-style=shell" "") |
| 1762 | (tramp-get-remote-stat vec) | 1774 | (tramp-get-remote-stat vec) |
| 1763 | (if (eq id-format 'integer) "%ue0" "//%U//") | 1775 | tramp-stat-marker tramp-stat-marker |
| 1764 | (if (eq id-format 'integer) "%ge0" "//%G//")))) | 1776 | tramp-stat-marker tramp-stat-marker |
| 1777 | (if (eq id-format 'integer) | ||
| 1778 | "%ue0" (concat tramp-stat-marker "%U" tramp-stat-marker)) | ||
| 1779 | (if (eq id-format 'integer) | ||
| 1780 | "%ge0" (concat tramp-stat-marker "%G" tramp-stat-marker)) | ||
| 1781 | tramp-stat-marker tramp-stat-marker | ||
| 1782 | tramp-stat-quoted-marker))) | ||
| 1765 | 1783 | ||
| 1766 | ;; This function should return "foo/" for directories and "bar" for | 1784 | ;; This function should return "foo/" for directories and "bar" for |
| 1767 | ;; files. | 1785 | ;; files. |
| @@ -5023,10 +5041,18 @@ raises an error." | |||
| 5023 | Convert file mode bits to string and set virtual device number. | 5041 | Convert file mode bits to string and set virtual device number. |
| 5024 | Return ATTR." | 5042 | Return ATTR." |
| 5025 | (when attr | 5043 | (when attr |
| 5026 | ;; Remove color escape sequences from symlink. | 5044 | ;; Convert symlink from `tramp-do-file-attributes-with-stat'. |
| 5045 | (when (consp (car attr)) | ||
| 5046 | (if (and (stringp (caar attr)) | ||
| 5047 | (string-match ".+ -> .\\(.+\\)." (caar attr))) | ||
| 5048 | (setcar attr (match-string 1 (caar attr))) | ||
| 5049 | (setcar attr nil))) | ||
| 5050 | ;; Remove color escape sequences and double slashes from symlink. | ||
| 5027 | (when (stringp (car attr)) | 5051 | (when (stringp (car attr)) |
| 5028 | (while (string-match tramp-color-escape-sequence-regexp (car attr)) | 5052 | (while (string-match tramp-color-escape-sequence-regexp (car attr)) |
| 5029 | (setcar attr (replace-match "" nil nil (car attr))))) | 5053 | (setcar attr (replace-match "" nil nil (car attr)))) |
| 5054 | (while (string-match "//" (car attr)) | ||
| 5055 | (setcar attr (replace-match "/" nil nil (car attr))))) | ||
| 5030 | ;; Convert uid and gid. Use -1 as indication of unusable value. | 5056 | ;; Convert uid and gid. Use -1 as indication of unusable value. |
| 5031 | (when (and (numberp (nth 2 attr)) (< (nth 2 attr) 0)) | 5057 | (when (and (numberp (nth 2 attr)) (< (nth 2 attr) 0)) |
| 5032 | (setcar (nthcdr 2 attr) -1)) | 5058 | (setcar (nthcdr 2 attr) -1)) |
| @@ -5067,12 +5093,6 @@ Return ATTR." | |||
| 5067 | ;; Convert directory indication bit. | 5093 | ;; Convert directory indication bit. |
| 5068 | (when (string-match "^d" (nth 8 attr)) | 5094 | (when (string-match "^d" (nth 8 attr)) |
| 5069 | (setcar attr t)) | 5095 | (setcar attr t)) |
| 5070 | ;; Convert symlink from `tramp-do-file-attributes-with-stat'. | ||
| 5071 | (when (consp (car attr)) | ||
| 5072 | (if (and (stringp (caar attr)) | ||
| 5073 | (string-match ".+ -> .\\(.+\\)." (caar attr))) | ||
| 5074 | (setcar attr (match-string 1 (caar attr))) | ||
| 5075 | (setcar attr nil))) | ||
| 5076 | ;; Set file's gid change bit. | 5096 | ;; Set file's gid change bit. |
| 5077 | (setcar (nthcdr 9 attr) | 5097 | (setcar (nthcdr 9 attr) |
| 5078 | (if (numberp (nth 3 attr)) | 5098 | (if (numberp (nth 3 attr)) |
diff --git a/test/automated/tramp-tests.el b/test/automated/tramp-tests.el index e6f77e42499..498a0cfa7da 100644 --- a/test/automated/tramp-tests.el +++ b/test/automated/tramp-tests.el | |||
| @@ -1058,6 +1058,13 @@ This tests also `file-readable-p' and `file-regular-p'." | |||
| 1058 | (file-truename tramp-test-temporary-file-directory)) | 1058 | (file-truename tramp-test-temporary-file-directory)) |
| 1059 | (tmp-name1 (tramp--test-make-temp-name)) | 1059 | (tmp-name1 (tramp--test-make-temp-name)) |
| 1060 | (tmp-name2 (tramp--test-make-temp-name)) | 1060 | (tmp-name2 (tramp--test-make-temp-name)) |
| 1061 | ;; File name with "//". | ||
| 1062 | (tmp-name3 | ||
| 1063 | (format | ||
| 1064 | "%s%s" | ||
| 1065 | (file-remote-p tmp-name1) | ||
| 1066 | (replace-regexp-in-string | ||
| 1067 | "/" "//" (file-remote-p tmp-name1 'localname)))) | ||
| 1061 | attr) | 1068 | attr) |
| 1062 | (unwind-protect | 1069 | (unwind-protect |
| 1063 | (progn | 1070 | (progn |
| @@ -1099,8 +1106,24 @@ This tests also `file-readable-p' and `file-regular-p'." | |||
| 1099 | (file-error | 1106 | (file-error |
| 1100 | (should (string-equal (error-message-string err) | 1107 | (should (string-equal (error-message-string err) |
| 1101 | "make-symbolic-link not supported")))) | 1108 | "make-symbolic-link not supported")))) |
| 1102 | (delete-file tmp-name1) | ||
| 1103 | 1109 | ||
| 1110 | ;; Check, that "//" in symlinks are handled properly. | ||
| 1111 | (with-temp-buffer | ||
| 1112 | (let ((default-directory tramp-test-temporary-file-directory)) | ||
| 1113 | (shell-command | ||
| 1114 | (format | ||
| 1115 | "ln -s %s %s" | ||
| 1116 | (tramp-file-name-localname (tramp-dissect-file-name tmp-name3)) | ||
| 1117 | (tramp-file-name-localname (tramp-dissect-file-name tmp-name2))) | ||
| 1118 | t))) | ||
| 1119 | (when (file-symlink-p tmp-name2) | ||
| 1120 | (setq attr (file-attributes tmp-name2)) | ||
| 1121 | (should (string-equal | ||
| 1122 | (car attr) | ||
| 1123 | (file-remote-p (file-truename tmp-name3) 'localname))) | ||
| 1124 | (delete-file tmp-name2)) | ||
| 1125 | |||
| 1126 | (delete-file tmp-name1) | ||
| 1104 | (make-directory tmp-name1) | 1127 | (make-directory tmp-name1) |
| 1105 | (should (file-exists-p tmp-name1)) | 1128 | (should (file-exists-p tmp-name1)) |
| 1106 | (should (file-readable-p tmp-name1)) | 1129 | (should (file-readable-p tmp-name1)) |
| @@ -1109,7 +1132,9 @@ This tests also `file-readable-p' and `file-regular-p'." | |||
| 1109 | (should (eq (car attr) t))) | 1132 | (should (eq (car attr) t))) |
| 1110 | 1133 | ||
| 1111 | ;; Cleanup. | 1134 | ;; Cleanup. |
| 1112 | (ignore-errors (delete-directory tmp-name1))))) | 1135 | (ignore-errors (delete-directory tmp-name1)) |
| 1136 | (ignore-errors (delete-file tmp-name1)) | ||
| 1137 | (ignore-errors (delete-file tmp-name2))))) | ||
| 1113 | 1138 | ||
| 1114 | (ert-deftest tramp-test19-directory-files-and-attributes () | 1139 | (ert-deftest tramp-test19-directory-files-and-attributes () |
| 1115 | "Check `directory-files-and-attributes'." | 1140 | "Check `directory-files-and-attributes'." |
| @@ -1198,6 +1223,8 @@ This tests also `make-symbolic-link', `file-truename' and `add-name-to-file'." | |||
| 1198 | (tmp-name1 (tramp--test-make-temp-name)) | 1223 | (tmp-name1 (tramp--test-make-temp-name)) |
| 1199 | (tmp-name2 (tramp--test-make-temp-name)) | 1224 | (tmp-name2 (tramp--test-make-temp-name)) |
| 1200 | (tmp-name3 (tramp--test-make-temp-name 'local))) | 1225 | (tmp-name3 (tramp--test-make-temp-name 'local))) |
| 1226 | |||
| 1227 | ;; Check `make-symbolic-link'. | ||
| 1201 | (unwind-protect | 1228 | (unwind-protect |
| 1202 | (progn | 1229 | (progn |
| 1203 | (write-region "foo" nil tmp-name1) | 1230 | (write-region "foo" nil tmp-name1) |
| @@ -1223,6 +1250,7 @@ This tests also `make-symbolic-link', `file-truename' and `add-name-to-file'." | |||
| 1223 | (delete-file tmp-name1) | 1250 | (delete-file tmp-name1) |
| 1224 | (delete-file tmp-name2))) | 1251 | (delete-file tmp-name2))) |
| 1225 | 1252 | ||
| 1253 | ;; Check `add-name-to-file'. | ||
| 1226 | (unwind-protect | 1254 | (unwind-protect |
| 1227 | (progn | 1255 | (progn |
| 1228 | (write-region "foo" nil tmp-name1) | 1256 | (write-region "foo" nil tmp-name1) |
| @@ -1240,6 +1268,7 @@ This tests also `make-symbolic-link', `file-truename' and `add-name-to-file'." | |||
| 1240 | (delete-file tmp-name1) | 1268 | (delete-file tmp-name1) |
| 1241 | (delete-file tmp-name2))) | 1269 | (delete-file tmp-name2))) |
| 1242 | 1270 | ||
| 1271 | ;; Check `file-truename'. | ||
| 1243 | (unwind-protect | 1272 | (unwind-protect |
| 1244 | (progn | 1273 | (progn |
| 1245 | (write-region "foo" nil tmp-name1) | 1274 | (write-region "foo" nil tmp-name1) |