all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
* "Renaming: permission denied" file-error in Windows
@ 2011-12-11  0:16 LynX
  2011-12-11  5:30 ` Eli Zaretskii
  0 siblings, 1 reply; 21+ messages in thread
From: LynX @ 2011-12-11  0:16 UTC (permalink / raw)
  To: emacs-devel

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))



^ permalink raw reply	[flat|nested] 21+ messages in thread

end of thread, other threads:[~2012-01-07  9:54 UTC | newest]

Thread overview: 21+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-12-11  0:16 "Renaming: permission denied" file-error in Windows LynX
2011-12-11  5:30 ` 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

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.