diff --git a/lisp/net/tramp-adb.el b/lisp/net/tramp-adb.el index 3a5f4732ade..fb84aa11085 100644 --- a/lisp/net/tramp-adb.el +++ b/lisp/net/tramp-adb.el @@ -709,15 +709,16 @@ PRESERVE-UID-GID and PRESERVE-EXTENDED-ATTRIBUTES are completely ignored." (let ((t1 (tramp-tramp-file-p filename)) (t2 (tramp-tramp-file-p newname))) (with-parsed-tramp-file-name (if t1 filename newname) nil + (when (and (not ok-if-already-exists) (file-exists-p newname)) + (tramp-error v 'file-already-exists newname)) + (when (and (file-directory-p newname) (not (directory-name-p newname))) + (tramp-error v 'file-error "File is a directory %s" newname)) + (with-tramp-progress-reporter v 0 (format "Copying %s to %s" filename newname) - (if (and t1 t2 (tramp-equal-remote filename newname)) (let ((l1 (tramp-compat-file-local-name filename)) (l2 (tramp-compat-file-local-name newname))) - (when (and (not ok-if-already-exists) - (file-exists-p newname)) - (tramp-error v 'file-already-exists newname)) ;; We must also flush the cache of the directory, ;; because `file-attributes' reads the values from ;; there. @@ -788,17 +789,18 @@ PRESERVE-UID-GID and PRESERVE-EXTENDED-ATTRIBUTES are completely ignored." (let ((t1 (tramp-tramp-file-p filename)) (t2 (tramp-tramp-file-p newname))) (with-parsed-tramp-file-name (if t1 filename newname) nil + (when (and (not ok-if-already-exists) (file-exists-p newname)) + (tramp-error v 'file-already-exists newname)) + (when (and (file-directory-p newname) (not (directory-name-p newname))) + (tramp-error v 'file-error "File is a directory %s" newname)) + (with-tramp-progress-reporter v 0 (format "Renaming %s to %s" filename newname) - (if (and t1 t2 (tramp-equal-remote filename newname) (not (file-directory-p filename))) (let ((l1 (tramp-compat-file-local-name filename)) (l2 (tramp-compat-file-local-name newname))) - (when (and (not ok-if-already-exists) - (file-exists-p newname)) - (tramp-error v 'file-already-exists newname)) ;; We must also flush the cache of the directory, because ;; `file-attributes' reads the values from there. (tramp-flush-file-properties v (file-name-directory l1)) diff --git a/lisp/net/tramp-gvfs.el b/lisp/net/tramp-gvfs.el index c9ed674bc27..9d45e6a8ce9 100644 --- a/lisp/net/tramp-gvfs.el +++ b/lisp/net/tramp-gvfs.el @@ -765,6 +765,8 @@ file names." (with-parsed-tramp-file-name (if t1 filename newname) nil (when (and (not ok-if-already-exists) (file-exists-p newname)) (tramp-error v 'file-already-exists newname)) + (when (and (file-directory-p newname) (not (directory-name-p newname))) + (tramp-error v 'file-error "File is a directory %s" newname)) (if (or (and equal-remote (tramp-get-connection-property v "direct-copy-failed" nil)) diff --git a/lisp/net/tramp-rclone.el b/lisp/net/tramp-rclone.el index 22a8ca3ac6c..9b3eab34771 100644 --- a/lisp/net/tramp-rclone.el +++ b/lisp/net/tramp-rclone.el @@ -215,6 +215,8 @@ file names." (with-parsed-tramp-file-name (if t1 filename newname) nil (when (and (not ok-if-already-exists) (file-exists-p newname)) (tramp-error v 'file-already-exists newname)) + (when (and (file-directory-p newname) (not (directory-name-p newname))) + (tramp-error v 'file-error "File is a directory %s" newname)) (if (or (and t1 (not (tramp-rclone-file-name-p filename))) (and t2 (not (tramp-rclone-file-name-p newname)))) diff --git a/lisp/net/tramp-sh.el b/lisp/net/tramp-sh.el index d488e5ccf97..b8b981bc1a6 100644 --- a/lisp/net/tramp-sh.el +++ b/lisp/net/tramp-sh.el @@ -1995,6 +1995,8 @@ file names." (with-parsed-tramp-file-name (if t1 filename newname) nil (when (and (not ok-if-already-exists) (file-exists-p newname)) (tramp-error v 'file-already-exists newname)) + (when (and (file-directory-p newname) (not (directory-name-p newname))) + (tramp-error v 'file-error "File is a directory %s" newname)) (with-tramp-progress-reporter v 0 (format "%s %s to %s" diff --git a/lisp/net/tramp-smb.el b/lisp/net/tramp-smb.el index 099277d496a..9b87ed40cb0 100644 --- a/lisp/net/tramp-smb.el +++ b/lisp/net/tramp-smb.el @@ -588,9 +588,11 @@ PRESERVE-UID-GID and PRESERVE-EXTENDED-ATTRIBUTES are completely ignored." (expand-file-name (file-name-nondirectory filename) newname))) (with-parsed-tramp-file-name newname nil - (when (and (not ok-if-already-exists) - (file-exists-p newname)) + (when (and (not ok-if-already-exists) (file-exists-p newname)) (tramp-error v 'file-already-exists newname)) + (when (and (file-directory-p newname) + (not (directory-name-p newname))) + (tramp-error v 'file-error "File is a directory %s" newname)) ;; We must also flush the cache of the directory, because ;; `file-attributes' reads the values from there. @@ -1335,48 +1337,49 @@ component is used as the target of the symlink." (setq filename (expand-file-name filename) newname (expand-file-name newname)) - (when (and (not ok-if-already-exists) - (file-exists-p newname)) - (tramp-error - (tramp-dissect-file-name - (if (tramp-tramp-file-p filename) filename newname)) - 'file-already-exists newname)) + (with-parsed-tramp-file-name + (if (tramp-tramp-file-p filename) filename newname) nil + (when (and (not ok-if-already-exists) (file-exists-p newname)) + (tramp-error v 'file-already-exists newname)) + (when (and (file-directory-p newname) (not (directory-name-p newname))) + (tramp-error v 'file-error "File is a directory %s" newname)) - (with-tramp-progress-reporter - (tramp-dissect-file-name - (if (tramp-tramp-file-p filename) filename newname)) - 0 (format "Renaming %s to %s" filename newname) + (with-tramp-progress-reporter + v 0 (format "Renaming %s to %s" filename newname) - (if (and (not (file-exists-p newname)) - (tramp-equal-remote filename newname) - (string-equal - (tramp-smb-get-share (tramp-dissect-file-name filename)) - (tramp-smb-get-share (tramp-dissect-file-name newname)))) - ;; We can rename directly. - (with-parsed-tramp-file-name filename v1 - (with-parsed-tramp-file-name newname v2 + (if (and (not (file-exists-p newname)) + (tramp-equal-remote filename newname) + (string-equal + (tramp-smb-get-share (tramp-dissect-file-name filename)) + (tramp-smb-get-share (tramp-dissect-file-name newname)))) + ;; We can rename directly. + (with-parsed-tramp-file-name filename v1 + (with-parsed-tramp-file-name newname v2 - ;; We must also flush the cache of the directory, because - ;; `file-attributes' reads the values from there. - (tramp-flush-file-properties v1 (file-name-directory v1-localname)) - (tramp-flush-file-properties v1 v1-localname) - (tramp-flush-file-properties v2 (file-name-directory v2-localname)) - (tramp-flush-file-properties v2 v2-localname) - (unless (tramp-smb-get-share v2) - (tramp-error - v2 'file-error "Target `%s' must contain a share name" newname)) - (unless (tramp-smb-send-command - v2 (format "rename \"%s\" \"%s\"" - (tramp-smb-get-localname v1) - (tramp-smb-get-localname v2))) - (tramp-error v2 'file-error "Cannot rename `%s'" filename)))) + ;; We must also flush the cache of the directory, because + ;; `file-attributes' reads the values from there. + (tramp-flush-file-properties + v1 (file-name-directory v1-localname)) + (tramp-flush-file-properties v1 v1-localname) + (tramp-flush-file-properties + v2 (file-name-directory v2-localname)) + (tramp-flush-file-properties v2 v2-localname) + (unless (tramp-smb-get-share v2) + (tramp-error + v2 'file-error + "Target `%s' must contain a share name" newname)) + (unless (tramp-smb-send-command + v2 (format "rename \"%s\" \"%s\"" + (tramp-smb-get-localname v1) + (tramp-smb-get-localname v2))) + (tramp-error v2 'file-error "Cannot rename `%s'" filename)))) - ;; We must rename via copy. - (copy-file - filename newname ok-if-already-exists 'keep-time 'preserve-uid-gid) - (if (file-directory-p filename) - (delete-directory filename 'recursive) - (delete-file filename))))) + ;; We must rename via copy. + (copy-file + filename newname ok-if-already-exists 'keep-time 'preserve-uid-gid) + (if (file-directory-p filename) + (delete-directory filename 'recursive) + (delete-file filename)))))) (defun tramp-smb-action-set-acl (proc vec) "Set ACL data." diff --git a/lisp/net/tramp-sudoedit.el b/lisp/net/tramp-sudoedit.el index bbe780099d5..0ded85fb554 100644 --- a/lisp/net/tramp-sudoedit.el +++ b/lisp/net/tramp-sudoedit.el @@ -244,6 +244,8 @@ absolute file names." (with-parsed-tramp-file-name (if t1 filename newname) nil (when (and (not ok-if-already-exists) (file-exists-p newname)) (tramp-error v 'file-already-exists newname)) + (when (and (file-directory-p newname) (not (directory-name-p newname))) + (tramp-error v 'file-error "File is a directory %s" newname)) (if (or (and (file-remote-p filename) (not t1)) (and (file-remote-p newname) (not t2))) diff --git a/test/lisp/net/tramp-tests.el b/test/lisp/net/tramp-tests.el index 77b2c263ff8..a12e41a8822 100644 --- a/test/lisp/net/tramp-tests.el +++ b/test/lisp/net/tramp-tests.el @@ -2394,7 +2394,10 @@ This checks also `file-name-as-directory', `file-name-directory', (when (and (tramp--test-expensive-test) (tramp--test-emacs26-p)) (should-error (copy-file source target) - :type 'file-already-exists)) + :type 'file-already-exists) + (should-error + (copy-file source target 'ok) + :type 'file-error)) (copy-file source (file-name-as-directory target)) (should (file-exists-p @@ -2508,7 +2511,10 @@ This checks also `file-name-as-directory', `file-name-directory', (when (and (tramp--test-expensive-test) (tramp--test-emacs26-p)) (should-error (rename-file source target) - :type 'file-already-exists)) + :type 'file-already-exists) + (should-error + (rename-file source target 'ok) + :type 'file-error)) (rename-file source (file-name-as-directory target)) (should-not (file-exists-p source)) (should