Mail Archives: cygwin-developers/2000/04/17/19:50:36
This patch seems to make sense but I was wondering if you'd be interested
in going a step further? If, for some reason, the MoveFile of an existing
file fails, the target file will be gone. rename on UNIX doesn't work
this way.
To fix this will require renaming the target file, then doing the MoveFile.
If the MoveFile works then the renamed target file is deleted. Otherwise,
the target file is renamed back.
Do you have the time to implement something like this?
cgf
On Mon, Apr 17, 2000 at 01:37:24PM +0900, Kazuhiro Fujieda wrote:
>rename() simply deletes a file on remote drives when its source
>and destination are identical without distinction of their case.
>The following session illustrates this problem.
>
>/jizai/tmp $ touch aa (A remote drive is mounted on /jizai)
>/jizai/tmp $ ls -l aa
>-rw-r--r-- 1 fujieda Domain U 0 Apr 17 13:18 aa
>/jizai/tmp $ mv aa AA
>mv: cannot move `aa' to `AA': No such file or directory
>/jizai/tmp $ ls -l aa
>ls: aa: No such file or directory
>/jizai/tmp $ ls -l AA
>ls: AA: No such file or directory
>
>It is caused by MoveFileEx(..., MOVEFILE_REPLACE_EXISTING) in
>_rename().
>
>The following patch modify _rename() so that it tries MoveFile()
>at first, then tries MoveFileEx(..., MOVEFILE_REPLACE_EXISTING)
>on WinNT or the loop of DeleteFileA() and MoveFile() on Win9x.
>
>ChangeLog:
>Mon Apr 17 12:08:47 2000 Kazuhiro Fujieda <fujieda AT jaist DOT ac DOT jp>
> * syscalls.cc (_rename): Try MoveFile() at first before
> MoveFileEx(..., MOVEFILE_REPLACE_EXISTING).
>
>Index: syscalls.cc
>===================================================================
>RCS file: /cvs/src/src/winsup/cygwin/syscalls.cc,v
>retrieving revision 1.14
>diff -u -p -r1.14 syscalls.cc
>--- syscalls.cc 2000/04/16 22:57:05 1.14
>+++ syscalls.cc 2000/04/17 03:58:43
>@@ -1200,42 +1200,44 @@ _rename (const char *oldpath, const char
> SetFileAttributesA (real_new.get_win32 (), newatts & ~ FILE_ATTRIBUTE_READONLY);
> }
>
>- /* First make sure we have the permissions */
>- if (!MoveFileEx (real_old.get_win32 (), real_new.get_win32 (), MOVEFILE_REPLACE_EXISTING))
>- {
>- res = -1;
>+ if (!MoveFile (real_old.get_win32 (), real_new.get_win32 ()))
>+ res = -1;
>+
>+ if (res == 0 || GetLastError () != ERROR_ALREADY_EXISTS)
>+ goto done;
>
>- /* !!! fixme, check for windows version before trying this.. */
>- if (GetLastError () == ERROR_CALL_NOT_IMPLEMENTED)
>+ if (os_being_run == winNT)
>+ {
>+ if (MoveFileEx (real_old.get_win32 (), real_new.get_win32 (),
>+ MOVEFILE_REPLACE_EXISTING))
>+ res = 0;
>+ }
>+ else
>+ {
>+ syscall_printf ("try win95 hack");
>+ for (;;)
> {
>- /* How sad, we must be on win95, try it the stupid way */
>- syscall_printf ("try win95 hack");
>- for (;;)
>+ if (!DeleteFileA (real_new.get_win32 ()) &&
>+ GetLastError () != ERROR_FILE_NOT_FOUND)
>+ {
>+ syscall_printf ("deleting %s to be paranoid",
>+ real_new.get_win32 ());
>+ break;
>+ }
>+ else
> {
> if (MoveFile (real_old.get_win32 (), real_new.get_win32 ()))
> {
> res = 0;
> break;
> }
>-
>- if (GetLastError () != ERROR_ALREADY_EXISTS)
>- {
>- syscall_printf ("%s already_exists", real_new.get_win32 ());
>- break;
>- }
>-
>- if (!DeleteFileA (real_new.get_win32 ()) &&
>- GetLastError () != ERROR_FILE_NOT_FOUND)
>- {
>- syscall_printf ("deleting %s to be paranoid",
>- real_new.get_win32 ());
>- break;
>- }
> }
> }
>- if (res)
>- __seterrno ();
> }
>+
>+done:
>+ if (res)
>+ __seterrno ();
>
> if (res == 0)
> {
>
>____
> | AIST Kazuhiro Fujieda <fujieda AT jaist DOT ac DOT jp>
> | HOKURIKU School of Information Science
>o_/ 1990 Japan Advanced Institute of Science and Technology
--
cgf AT cygnus DOT com Cygnus Solutions, a Red Hat company
http://sourcware.cygnus.com/ http://www.redhat.com/
- Raw text -