delorie.com/archives/browse.cgi   search  
Mail Archives: cygwin-developers/2000/04/17/19:50:36

Mailing-List: contact cygwin-developers-help AT sourceware DOT cygnus DOT com; run by ezmlm
List-Subscribe: <mailto:cygwin-developers-subscribe AT sourceware DOT cygnus DOT com>
List-Archive: <http://sourceware.cygnus.com/ml/cygwin-developers/>
List-Post: <mailto:cygwin-developers AT sourceware DOT cygnus DOT com>
List-Help: <mailto:cygwin-developers-help AT sourceware DOT cygnus DOT com>, <http://sourceware.cygnus.com/ml/#faqs>
Sender: cygwin-developers-owner AT sourceware DOT cygnus DOT com
Delivered-To: mailing list cygwin-developers AT sourceware DOT cygnus DOT com
From: Chris Faylor <cgf AT cygnus DOT com>
Date: Mon, 17 Apr 2000 20:50:14 -0400
To: cygwin-developers AT sourceware DOT cygnus DOT com
Subject: Re: rename() is sometimes unsafe on remote drives.
Message-ID: <20000417205014.A5050@cygnus.com>
Reply-To: cygwin-developers AT sourceware DOT cygnus DOT com
Mail-Followup-To: cgf AT cygnus DOT com, cygwin-developers AT sourceware DOT cygnus DOT com
References: <s1spurp737f DOT fsf AT jaist DOT ac DOT jp>
Mime-Version: 1.0
User-Agent: Mutt/1.1.8i
In-Reply-To: <s1spurp737f.fsf@jaist.ac.jp>; from fujieda@jaist.ac.jp on Mon, Apr 17, 2000 at 01:37:24PM +0900

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 -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019