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