(file-remote-p . tramp-handle-file-remote-p)
;; `file-selinux-context' performed by default handler.
(file-symlink-p . tramp-handle-file-symlink-p)
- ;; `file-truename' performed by default handler.
+ (file-truename . tramp-smb-handle-file-truename)
(file-writable-p . tramp-smb-handle-file-writable-p)
(find-backup-file-name . tramp-handle-find-backup-file-name)
;; `find-file-noselect' performed by default handler.
(nth 0 x))))
(tramp-smb-get-file-entries directory))))))))
+(defun tramp-smb-handle-file-truename (filename)
+ "Like `file-truename' for Tramp files."
+ (format
+ "%s%s"
+ (with-parsed-tramp-file-name (expand-file-name filename) nil
+ (tramp-make-tramp-file-name
+ method user domain host port
+ (with-tramp-file-property v localname "file-truename"
+ (funcall
+ (if (tramp-compat-file-name-quoted-p localname)
+ 'tramp-compat-file-name-quote 'identity)
+ ;; We don't follow symlink of symlink.
+ (or (file-symlink-p filename) localname)))))
+
+ ;; Preserve trailing "/".
+ (if (string-equal (file-name-nondirectory filename) "") "/" "")))
+
(defun tramp-smb-handle-file-writable-p (filename)
"Like `file-writable-p' for Tramp files."
(if (file-exists-p filename)
(unless
(tramp-smb-send-command
- v
- (format "symlink \"%s\" \"%s\"" target (tramp-smb-get-localname v)))
+ v (format "symlink \"%s\" \"%s\""
+ (tramp-compat-file-name-unquote target)
+ (tramp-smb-get-localname v)))
(tramp-error
v 'file-error
"error with make-symbolic-link, see buffer `%s' for details"
(ignore-errors (delete-directory tmp-name1 'recursive))
(ignore-errors (delete-directory tmp-name2 'recursive))))))
+;; Method "smb" supports `make-symbolic-link' only if the remote host
+;; has CIFS capabilities. tramp-adb.el and tramp-gvfs.el do not
+;; support symbolic links at all.
+(defmacro tramp--test-ignore-make-symbolic-link-error (&rest body)
+ "Run BODY, ignoring \"make-symbolic-link not supported\" file error."
+ (declare (indent defun) (debug t))
+ `(condition-case err
+ (progn ,@body)
+ ((error quit debug)
+ (unless (and (eq (car err) 'file-error)
+ (string-equal (error-message-string err)
+ "make-symbolic-link not supported"))
+ (signal (car err) (cdr err))))))
+
(ert-deftest tramp-test18-file-attributes ()
"Check `file-attributes'.
This tests also `file-readable-p', `file-regular-p' and
(should (stringp (nth 2 attr))) ;; Uid.
(should (stringp (nth 3 attr))) ;; Gid.
- (condition-case err
- (progn
- (when (tramp--test-sh-p)
- (should (file-ownership-preserved-p tmp-name2 'group)))
- (make-symbolic-link tmp-name1 tmp-name2)
- (should (file-exists-p tmp-name2))
- (should (file-symlink-p tmp-name2))
- (when (tramp--test-sh-p)
- (should (file-ownership-preserved-p tmp-name2 'group)))
- (setq attr (file-attributes tmp-name2))
- (should
- (string-equal
- (funcall
- (if quoted 'tramp-compat-file-name-quote 'identity)
- (car attr))
- (file-remote-p (file-truename tmp-name1) 'localname)))
- (delete-file tmp-name2))
- (file-error
- (should (string-equal (error-message-string err)
- "make-symbolic-link not supported"))))
+ (tramp--test-ignore-make-symbolic-link-error
+ (when (tramp--test-sh-p)
+ (should (file-ownership-preserved-p tmp-name2 'group)))
+ (make-symbolic-link tmp-name1 tmp-name2)
+ (should (file-exists-p tmp-name2))
+ (should (file-symlink-p tmp-name2))
+ (when (tramp--test-sh-p)
+ (should (file-ownership-preserved-p tmp-name2 'group)))
+ (setq attr (file-attributes tmp-name2))
+ (should
+ (string-equal
+ (funcall
+ (if quoted 'tramp-compat-file-name-quote 'identity)
+ (car attr))
+ (file-remote-p (file-truename tmp-name1) 'localname)))
+ (delete-file tmp-name2))
;; Check, that "//" in symlinks are handled properly.
(with-temp-buffer
;; Check `make-symbolic-link'.
(unwind-protect
- (progn
+ (tramp--test-ignore-make-symbolic-link-error
(write-region "foo" nil tmp-name1)
(should (file-exists-p tmp-name1))
- ;; Method "smb" supports `make-symbolic-link' only if the
- ;; remote host has CIFS capabilities. tramp-adb.el and
- ;; tramp-gvfs.el do not support symbolic links at all.
- (condition-case err
- (make-symbolic-link tmp-name1 tmp-name2)
- (file-error
- (skip-unless
- (not (string-equal (error-message-string err)
- "make-symbolic-link not supported")))))
+ (make-symbolic-link tmp-name1 tmp-name2)
(should
(string-equal
(funcall
(should-not (file-symlink-p tmp-name2))
(should (file-regular-p tmp-name2))
;; `tmp-name3' is a local file name.
- (should-error (add-name-to-file tmp-name1 tmp-name3)))
+ (should-error
+ (add-name-to-file tmp-name1 tmp-name3)
+ :type 'file-error))
;; Cleanup.
(ignore-errors
;; Check `file-truename'.
(unwind-protect
- (progn
+ (tramp--test-ignore-make-symbolic-link-error
(write-region "foo" nil tmp-name1)
(should (file-exists-p tmp-name1))
(make-symbolic-link tmp-name1 tmp-name2)
(copy-file file2 tmp-name1)
(should (file-exists-p file1))
- ;; Method "smb" supports `make-symbolic-link' only if the
- ;; remote host has CIFS capabilities. tramp-adb.el and
- ;; tramp-gvfs.el do not support symbolic links at all.
- (condition-case err
- (progn
- (make-symbolic-link file1 file3)
- (should (file-symlink-p file3))
- (should
- (string-equal
- (expand-file-name file1) (file-truename file3)))
- (should
- (string-equal
- (funcall
- (if quoted 'tramp-compat-file-name-quote 'identity)
- (car (file-attributes file3)))
- (file-remote-p (file-truename file1) 'localname)))
- ;; Check file contents.
- (with-temp-buffer
- (insert-file-contents file3)
- (should (string-equal (buffer-string) elt)))
- (delete-file file3))
- (file-error
- (should
- (string-equal (error-message-string err)
- "make-symbolic-link not supported"))))))
+ (tramp--test-ignore-make-symbolic-link-error
+ (make-symbolic-link file1 file3)
+ (should (file-symlink-p file3))
+ (should
+ (string-equal
+ (expand-file-name file1) (file-truename file3)))
+ (should
+ (string-equal
+ (funcall
+ (if quoted 'tramp-compat-file-name-quote 'identity)
+ (car (file-attributes file3)))
+ (file-remote-p (file-truename file1) 'localname)))
+ ;; Check file contents.
+ (with-temp-buffer
+ (insert-file-contents file3)
+ (should (string-equal (buffer-string) elt)))
+ (delete-file file3))))
;; Check file names.
(should (equal (directory-files
elt))
;; Check symlink in `directory-files-and-attributes'.
- (condition-case err
- (progn
- (make-symbolic-link file2 file3)
- (should (file-symlink-p file3))
- (should
- (string-equal
- (caar (directory-files-and-attributes
- file1 nil (regexp-quote elt1)))
- elt1))
- (should
- (string-equal
- (funcall
- (if quoted 'tramp-compat-file-name-quote 'identity)
- (cadr (car (directory-files-and-attributes
- file1 nil (regexp-quote elt1)))))
- (file-remote-p (file-truename file2) 'localname)))
- (delete-file file3)
- (should-not (file-exists-p file3)))
- (file-error
- (should (string-equal (error-message-string err)
- "make-symbolic-link not supported"))))
+ (tramp--test-ignore-make-symbolic-link-error
+ (make-symbolic-link file2 file3)
+ (should (file-symlink-p file3))
+ (should
+ (string-equal
+ (caar (directory-files-and-attributes
+ file1 nil (regexp-quote elt1)))
+ elt1))
+ (should
+ (string-equal
+ (funcall
+ (if quoted 'tramp-compat-file-name-quote 'identity)
+ (cadr (car (directory-files-and-attributes
+ file1 nil (regexp-quote elt1)))))
+ (file-remote-p (file-truename file2) 'localname)))
+ (delete-file file3)
+ (should-not (file-exists-p file3)))
(delete-file file2)
(should-not (file-exists-p file2))