all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
From: LynX <_LynX@bk.ru>
To: emacs-devel@gnu.org
Subject: "Renaming: permission denied" file-error in Windows
Date: Sun, 11 Dec 2011 02:16:45 +0200	[thread overview]
Message-ID: <4EE3F66D.2050003@bk.ru> (raw)

Hello,

I found that dired in Windows does not provide you possibility to move a 
directory to a new location if this new location resides on a different 
logical disk.

For instance you have two opened dired buffers: `c:\dir1' and 
`f:\dir2'. To move some files from `dir1' to `dir2' you can use "R", but 
if you try to move some directory from `dir1' to `dir2' you will get 
`Renaming: permission denied' error message.

The problem occurs when dired calls Emacs function which delegates the 
call to native POSIX function `rename'.

In Windows `rename' operates a bit different than in other systems. 
According to MSDN [http://msdn.microsoft.com/en-us/library/zw5t957f.aspx]:

-- "You can use rename to move a file from one directory or device to 
another by giving a different path in the newname argument. However, you 
cannot use rename to move a directory." --

Whereas, in standard POSIX spec such constraint was not found.

Following code workarounds this problem by wrapping dired function
`dired-rename-file'. So when `Renaming: permission denied' error occurs, 
it tries to move the directory again by moving each of it files 
recursively to a new destination, recreating the source directory with 
its subdirectory structure.

If it also fails to do this due to real permission problems then it 
sends original error message.

Regards,
LX


(defadvice dired-rename-file
   (around my-dired-rename-file
     (file newname ok-if-already-exists))
   "This advice definition helps to deal with
`Renaming: permission denied' error message when moving
directories between different logical disks in dired.
This is a Windows specific problem."
   (condition-case err
     ad-do-it
     (file-error
       (and
         (string-starts-with
           (error-message-string err)
           "Renaming: permission denied")
         (file-directory-p file)
         (move-directory-recursively file newname)))))
(ad-activate 'dired-rename-file t)


(defun move-directory-recursively (dir-src dir-dst)
   "Moves directory DIR-SRC to the DIR-DST recursively.
To move directory dir1 into the directory dir2 you should
call this function like as follows:
   (move-directory-recursively `dir1' `dir2/dir1')
To move content of the directory dir1 into the directory
dir2:
   (move-directory-recursively `dir1' `dir2')
If dir2 does not exist it will be created."
   (let ((queue (list (cons dir-src dir-dst)))
         dir-dst dir-src remove-later)
     (while queue
       (let ((dir-src-dst (car queue)))
         (setq dir-src (car dir-src-dst))
         (setq dir-dst (cdr dir-src-dst)))
       (setq queue (cdr queue))
       ;; if dir-dst is a file signal an error
       (and
         (file-exists-p dir-dst)
         (not (file-directory-p dir-dst))
         (signal 'file-error
           (format "Error: file %s exist" dir-dst)))
       ;; if dir-dst does not exist - create it
       (if (not (file-exists-p dir-dst))
         (make-directory dir-dst))
       (dolist (file (directory-files dir-src))
         (and
           (not (string= file "."))
           (not (string= file ".."))
           (let ((path (concat dir-src "/" file)))
             (if (file-directory-p path)
               ;; it is a directory
               (progn
                 ;; place it to the queue
                 (setq queue
                   (cons
                     (cons path (concat dir-dst "/" file))
                     queue))
                 ;; and store it path to remove it later
                 (push path remove-later))
               ;; not a dir
               (progn
                 (message
                   (format "Moving %s to %s" path dir-dst))
                 (rename-file path dir-dst)))))))
   ;; after we moved all content we can remove the
   ;; empty directories in dir-src
   (dolist (dir remove-later)
     (condition-case err
       (dired-delete-file dir 'always)
       (error ;; catch errors from failed deletions
         (dired-log "%s\n" err)))))
   (dired-delete-file dir-src 'always))



             reply	other threads:[~2011-12-11  0:16 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-12-11  0:16 LynX [this message]
2011-12-11  5:30 ` "Renaming: permission denied" file-error in Windows Eli Zaretskii
2011-12-11  5:32   ` Tekk
2011-12-11  5:42     ` Eli Zaretskii
2011-12-11  8:32   ` Paul Eggert
2011-12-11 12:51     ` Eli Zaretskii
2011-12-11 19:30       ` LynX
2011-12-11 18:03         ` Eli Zaretskii
2011-12-11 21:45           ` LynX
2011-12-11 21:31             ` Eli Zaretskii
2011-12-25  7:33               ` LynX
2011-12-25  9:39                 ` bug#10284: " Eli Zaretskii
2011-12-25  9:40                 ` Eli Zaretskii
2011-12-28 19:53                   ` bug#10284: " LynX
2011-12-29  6:18                     ` Eli Zaretskii
2011-12-30 19:31                       ` LynX
2011-12-30 20:23                         ` Eli Zaretskii
2011-12-30 21:35                           ` LynX
2011-12-31  6:48                             ` Eli Zaretskii
2012-01-06 20:46                               ` LynX
2012-01-07  9:54                                 ` Eli Zaretskii

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4EE3F66D.2050003@bk.ru \
    --to=_lynx@bk.ru \
    --cc=emacs-devel@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.