diff options
| author | Michael Albinus | 2025-03-16 14:17:38 +0100 |
|---|---|---|
| committer | Michael Albinus | 2025-03-16 14:17:38 +0100 |
| commit | b8104dadbf285d12c356d4cddd28ac3eaf05f263 (patch) | |
| tree | fdee9ed3209a12b0957d4a7699db51e0e2d05e8e /test | |
| parent | 03e33cbef3e33aa1ec843388d1671f7116a7347b (diff) | |
| download | emacs-b8104dadbf285d12c356d4cddd28ac3eaf05f263.tar.gz emacs-b8104dadbf285d12c356d4cddd28ac3eaf05f263.zip | |
Tramp: Handle symlinks to non-existing targets better
* lisp/net/tramp-gvfs.el (tramp-gvfs-do-copy-or-rename-file):
Don't use the truename.
* lisp/net/tramp-sh.el (tramp-do-copy-or-rename-file): Refactor. Handle
symlinks. (Bug#76678)
* lisp/net/tramp-smb.el (tramp-smb-errors): Add string.
(tramp-smb-handle-copy-file, tramp-smb-handle-rename-file):
Refactor.
* lisp/net/tramp-sudoedit.el (tramp-sudoedit-do-copy-or-rename-file):
Don't use the truename. Handle symlinks.
* lisp/net/tramp.el (tramp-barf-if-file-missing): Accept also symlinks.
(tramp-skeleton-file-exists-p): Handle non-existing symlink targets.
(tramp-skeleton-set-file-modes-times-uid-gid): Fix typo.
* test/lisp/net/tramp-tests.el (vc-handled-backends):
Suppress only if noninteractive.
(tramp-test11-copy-file, tramp-test12-rename-file)
(tramp-test18-file-attributes, tramp-test21-file-links)
(tramp--test-check-files): Adapt tests.
Diffstat (limited to 'test')
| -rw-r--r-- | test/lisp/net/tramp-tests.el | 89 |
1 files changed, 74 insertions, 15 deletions
diff --git a/test/lisp/net/tramp-tests.el b/test/lisp/net/tramp-tests.el index 1efafb68fbc..ccb3731fc09 100644 --- a/test/lisp/net/tramp-tests.el +++ b/test/lisp/net/tramp-tests.el | |||
| @@ -153,7 +153,7 @@ | |||
| 153 | tramp-error-show-message-timeout nil | 153 | tramp-error-show-message-timeout nil |
| 154 | tramp-persistency-file-name nil | 154 | tramp-persistency-file-name nil |
| 155 | tramp-verbose 0 | 155 | tramp-verbose 0 |
| 156 | vc-handled-backends nil) | 156 | vc-handled-backends (unless noninteractive vc-handled-backends)) |
| 157 | 157 | ||
| 158 | (defconst tramp-test-name-prefix "tramp-test" | 158 | (defconst tramp-test-name-prefix "tramp-test" |
| 159 | "Prefix to use for temporary test files.") | 159 | "Prefix to use for temporary test files.") |
| @@ -2871,7 +2871,9 @@ This checks also `file-name-as-directory', `file-name-directory', | |||
| 2871 | (dolist (quoted (if (tramp--test-expensive-test-p) '(nil t) '(nil))) | 2871 | (dolist (quoted (if (tramp--test-expensive-test-p) '(nil t) '(nil))) |
| 2872 | (let ((tmp-name1 (tramp--test-make-temp-name nil quoted)) | 2872 | (let ((tmp-name1 (tramp--test-make-temp-name nil quoted)) |
| 2873 | (tmp-name2 (tramp--test-make-temp-name nil quoted)) | 2873 | (tmp-name2 (tramp--test-make-temp-name nil quoted)) |
| 2874 | (tmp-name3 (tramp--test-make-temp-name 'local quoted))) | 2874 | (tmp-name3 (tramp--test-make-temp-name 'local quoted)) |
| 2875 | (tmp-name4 | ||
| 2876 | (file-name-nondirectory (tramp--test-make-temp-name 'local quoted)))) | ||
| 2875 | (dolist (source-target | 2877 | (dolist (source-target |
| 2876 | `(;; Copy on remote side. | 2878 | `(;; Copy on remote side. |
| 2877 | (,tmp-name1 . ,tmp-name2) | 2879 | (,tmp-name1 . ,tmp-name2) |
| @@ -2879,8 +2881,12 @@ This checks also `file-name-as-directory', `file-name-directory', | |||
| 2879 | (,tmp-name1 . ,tmp-name3) | 2881 | (,tmp-name1 . ,tmp-name3) |
| 2880 | ;; Copy from local side to remote side. | 2882 | ;; Copy from local side to remote side. |
| 2881 | (,tmp-name3 . ,tmp-name1))) | 2883 | (,tmp-name3 . ,tmp-name1))) |
| 2882 | (let ((source (car source-target)) | 2884 | (let* ((source (car source-target)) |
| 2883 | (target (cdr source-target))) | 2885 | (source-link |
| 2886 | (expand-file-name tmp-name4 (file-name-directory source))) | ||
| 2887 | (target (cdr source-target)) | ||
| 2888 | (target-link | ||
| 2889 | (expand-file-name tmp-name4 (file-name-directory target)))) | ||
| 2884 | 2890 | ||
| 2885 | ;; Copy simple file. | 2891 | ;; Copy simple file. |
| 2886 | (unwind-protect | 2892 | (unwind-protect |
| @@ -2905,6 +2911,26 @@ This checks also `file-name-as-directory', `file-name-directory', | |||
| 2905 | (ignore-errors (delete-file source)) | 2911 | (ignore-errors (delete-file source)) |
| 2906 | (ignore-errors (delete-file target))) | 2912 | (ignore-errors (delete-file target))) |
| 2907 | 2913 | ||
| 2914 | ;; Copy symlinked file. | ||
| 2915 | (unwind-protect | ||
| 2916 | (tramp--test-ignore-make-symbolic-link-error | ||
| 2917 | (write-region "foo" nil source-link) | ||
| 2918 | (should (file-exists-p source-link)) | ||
| 2919 | (make-symbolic-link tmp-name4 source) | ||
| 2920 | (should (file-exists-p source)) | ||
| 2921 | (should (string-equal (file-symlink-p source) tmp-name4)) | ||
| 2922 | (copy-file source target) | ||
| 2923 | ;; Some backends like tramp-gvfs.el do not create the | ||
| 2924 | ;; link on the target. | ||
| 2925 | (when (file-symlink-p target) | ||
| 2926 | (should (string-equal (file-symlink-p target) tmp-name4)))) | ||
| 2927 | |||
| 2928 | ;; Cleanup. | ||
| 2929 | (ignore-errors (delete-file source)) | ||
| 2930 | (ignore-errors (delete-file source-link)) | ||
| 2931 | (ignore-errors (delete-file target)) | ||
| 2932 | (ignore-errors (delete-file target-link))) | ||
| 2933 | |||
| 2908 | ;; Copy file to directory. | 2934 | ;; Copy file to directory. |
| 2909 | (unwind-protect | 2935 | (unwind-protect |
| 2910 | ;; This doesn't work on FTP. | 2936 | ;; This doesn't work on FTP. |
| @@ -2980,7 +3006,9 @@ This checks also `file-name-as-directory', `file-name-directory', | |||
| 2980 | (dolist (quoted (if (tramp--test-expensive-test-p) '(nil t) '(nil))) | 3006 | (dolist (quoted (if (tramp--test-expensive-test-p) '(nil t) '(nil))) |
| 2981 | (let ((tmp-name1 (tramp--test-make-temp-name nil quoted)) | 3007 | (let ((tmp-name1 (tramp--test-make-temp-name nil quoted)) |
| 2982 | (tmp-name2 (tramp--test-make-temp-name nil quoted)) | 3008 | (tmp-name2 (tramp--test-make-temp-name nil quoted)) |
| 2983 | (tmp-name3 (tramp--test-make-temp-name 'local quoted))) | 3009 | (tmp-name3 (tramp--test-make-temp-name 'local quoted)) |
| 3010 | (tmp-name4 | ||
| 3011 | (file-name-nondirectory (tramp--test-make-temp-name 'local quoted)))) | ||
| 2984 | (dolist (source-target | 3012 | (dolist (source-target |
| 2985 | `(;; Rename on remote side. | 3013 | `(;; Rename on remote side. |
| 2986 | (,tmp-name1 . ,tmp-name2) | 3014 | (,tmp-name1 . ,tmp-name2) |
| @@ -2988,8 +3016,12 @@ This checks also `file-name-as-directory', `file-name-directory', | |||
| 2988 | (,tmp-name1 . ,tmp-name3) | 3016 | (,tmp-name1 . ,tmp-name3) |
| 2989 | ;; Rename from local side to remote side. | 3017 | ;; Rename from local side to remote side. |
| 2990 | (,tmp-name3 . ,tmp-name1))) | 3018 | (,tmp-name3 . ,tmp-name1))) |
| 2991 | (let ((source (car source-target)) | 3019 | (let* ((source (car source-target)) |
| 2992 | (target (cdr source-target))) | 3020 | (source-link |
| 3021 | (expand-file-name tmp-name4 (file-name-directory source))) | ||
| 3022 | (target (cdr source-target)) | ||
| 3023 | (target-link | ||
| 3024 | (expand-file-name tmp-name4 (file-name-directory target)))) | ||
| 2993 | 3025 | ||
| 2994 | ;; Rename simple file. | 3026 | ;; Rename simple file. |
| 2995 | (unwind-protect | 3027 | (unwind-protect |
| @@ -3018,6 +3050,27 @@ This checks also `file-name-as-directory', `file-name-directory', | |||
| 3018 | (ignore-errors (delete-file source)) | 3050 | (ignore-errors (delete-file source)) |
| 3019 | (ignore-errors (delete-file target))) | 3051 | (ignore-errors (delete-file target))) |
| 3020 | 3052 | ||
| 3053 | ;; Rename symlinked file. | ||
| 3054 | (unwind-protect | ||
| 3055 | (tramp--test-ignore-make-symbolic-link-error | ||
| 3056 | (write-region "foo" nil source-link) | ||
| 3057 | (should (file-exists-p source-link)) | ||
| 3058 | (make-symbolic-link tmp-name4 source) | ||
| 3059 | (should (file-exists-p source)) | ||
| 3060 | (should (string-equal (file-symlink-p source) tmp-name4)) | ||
| 3061 | (rename-file source target) | ||
| 3062 | (should-not (file-exists-p source)) | ||
| 3063 | ;; Some backends like tramp-gvfs.el do not create the | ||
| 3064 | ;; link on the target. | ||
| 3065 | (when (file-symlink-p target) | ||
| 3066 | (should (string-equal (file-symlink-p target) tmp-name4)))) | ||
| 3067 | |||
| 3068 | ;; Cleanup. | ||
| 3069 | (ignore-errors (delete-file source)) | ||
| 3070 | (ignore-errors (delete-file source-link)) | ||
| 3071 | (ignore-errors (delete-file target)) | ||
| 3072 | (ignore-errors (delete-file target-link))) | ||
| 3073 | |||
| 3021 | ;; Rename file to directory. | 3074 | ;; Rename file to directory. |
| 3022 | (unwind-protect | 3075 | (unwind-protect |
| 3023 | (progn | 3076 | (progn |
| @@ -3814,6 +3867,18 @@ This tests also `access-file', `file-readable-p', | |||
| 3814 | (if quoted #'file-name-quote #'identity) | 3867 | (if quoted #'file-name-quote #'identity) |
| 3815 | (file-attribute-type attr)) | 3868 | (file-attribute-type attr)) |
| 3816 | (file-remote-p (file-truename tmp-name1) 'localname))) | 3869 | (file-remote-p (file-truename tmp-name1) 'localname))) |
| 3870 | (delete-file tmp-name2) | ||
| 3871 | |||
| 3872 | ;; A non-existent link target makes the file unaccessible. | ||
| 3873 | (make-symbolic-link "error" tmp-name2) | ||
| 3874 | (should (file-symlink-p tmp-name2)) | ||
| 3875 | (should-error | ||
| 3876 | (access-file tmp-name2 "error") | ||
| 3877 | :type 'file-missing) | ||
| 3878 | ;; `file-ownership-preserved-p' should return t for | ||
| 3879 | ;; symlinked files to a non-existing target. | ||
| 3880 | (when test-file-ownership-preserved-p | ||
| 3881 | (should (file-ownership-preserved-p tmp-name2 'group))) | ||
| 3817 | (delete-file tmp-name2)) | 3882 | (delete-file tmp-name2)) |
| 3818 | 3883 | ||
| 3819 | ;; Check, that "//" in symlinks are handled properly. | 3884 | ;; Check, that "//" in symlinks are handled properly. |
| @@ -4463,13 +4528,11 @@ This tests also `make-symbolic-link', `file-truename' and `add-name-to-file'." | |||
| 4463 | (make-symbolic-link tmp-name1 tmp-name2) | 4528 | (make-symbolic-link tmp-name1 tmp-name2) |
| 4464 | (should (file-symlink-p tmp-name1)) | 4529 | (should (file-symlink-p tmp-name1)) |
| 4465 | (should (file-symlink-p tmp-name2)) | 4530 | (should (file-symlink-p tmp-name2)) |
| 4466 | (should-not (file-regular-p tmp-name1)) | ||
| 4467 | (should-not (file-regular-p tmp-name2)) | ||
| 4468 | (should-error | 4531 | (should-error |
| 4469 | (file-truename tmp-name1) | 4532 | (file-regular-p tmp-name1) |
| 4470 | :type 'file-error) | 4533 | :type 'file-error) |
| 4471 | (should-error | 4534 | (should-error |
| 4472 | (file-truename tmp-name2) | 4535 | (file-regular-p tmp-name2) |
| 4473 | :type 'file-error)))) | 4536 | :type 'file-error)))) |
| 4474 | 4537 | ||
| 4475 | ;; Cleanup. | 4538 | ;; Cleanup. |
| @@ -7390,10 +7453,6 @@ This requires restrictions of file name syntax." | |||
| 7390 | (if quoted #'file-name-quote #'identity) | 7453 | (if quoted #'file-name-quote #'identity) |
| 7391 | (file-attribute-type (file-attributes file3))) | 7454 | (file-attribute-type (file-attributes file3))) |
| 7392 | (file-remote-p (file-truename file1) 'localname))) | 7455 | (file-remote-p (file-truename file1) 'localname))) |
| 7393 | ;; Check file contents. | ||
| 7394 | (with-temp-buffer | ||
| 7395 | (insert-file-contents file3) | ||
| 7396 | (should (string-equal (buffer-string) elt))) | ||
| 7397 | (delete-file file3)))) | 7456 | (delete-file file3)))) |
| 7398 | 7457 | ||
| 7399 | ;; Check file names. | 7458 | ;; Check file names. |