[Cmake-commits] CMake branch, next, updated. v2.8.10.2-1841-ga86384e

Brad King brad.king at kitware.com
Thu Jan 31 15:46:11 EST 2013


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "CMake".

The branch, next has been updated
       via  a86384eca61b8b9a6598a2d956894e196acbe767 (commit)
       via  2e4188e3f028f091acfcdc21ab71323e63102870 (commit)
      from  3deada4973a175503b6aef1abf8b4c271a7e1660 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=a86384eca61b8b9a6598a2d956894e196acbe767
commit a86384eca61b8b9a6598a2d956894e196acbe767
Merge: 3deada4 2e4188e
Author:     Brad King <brad.king at kitware.com>
AuthorDate: Thu Jan 31 15:46:09 2013 -0500
Commit:     CMake Topic Stage <kwrobot at kitware.com>
CommitDate: Thu Jan 31 15:46:09 2013 -0500

    Merge topic 'fix-atomic-rename-on-Windows' into next
    
    2e4188e Fix cmSystemTools::RenameFile race on Windows


http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=2e4188e3f028f091acfcdc21ab71323e63102870
commit 2e4188e3f028f091acfcdc21ab71323e63102870
Author:     Brad King <brad.king at kitware.com>
AuthorDate: Thu Jan 31 11:42:17 2013 -0500
Commit:     Brad King <brad.king at kitware.com>
CommitDate: Thu Jan 31 15:40:21 2013 -0500

    Fix cmSystemTools::RenameFile race on Windows
    
    Since commit d46d8df0 (Re-implemented cmGeneratedFileStream to look like a
    real stream and replace the destination file atomically, 2004-11-03) our
    RenameFile implementation tries to deal with MoveFile not replacing
    read-only files.  In order to avoid the Get/SetFileAttributes pair we used
    stat to test for existence of the destination file.  This has a race in
    which the destination could be created between the test for existence and
    the MoveFile call.
    
    Remove the stat call and use GetFileAttributes to detect whether the file
    exists.  This shortens the race but does not eliminate it.  Use a loop to
    try multiple times in case we lose the race.  While at it, drop Win9x
    support and always use MoveFileEx.

diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx
index c2521d9..1aa6486 100644
--- a/Source/cmSystemTools.cxx
+++ b/Source/cmSystemTools.cxx
@@ -1180,46 +1180,30 @@ bool cmSystemTools::CopyFileIfDifferent(const char* source,
 bool cmSystemTools::RenameFile(const char* oldname, const char* newname)
 {
 #ifdef _WIN32
-  /* On Windows the move functions will not replace existing files.
-     Check if the destination exists.  */
-  struct stat newFile;
-  if(stat(newname, &newFile) == 0)
-    {
-    /* The destination exists.  We have to replace it carefully.  The
-       MoveFileEx function does what we need but is not available on
-       Win9x.  */
-    OSVERSIONINFO osv;
-    DWORD attrs;
-
-    /* Make sure the destination is not read only.  */
-    attrs = GetFileAttributes(newname);
-    if(attrs & FILE_ATTRIBUTE_READONLY)
-      {
+# ifndef INVALID_FILE_ATTRIBUTES
+#  define INVALID_FILE_ATTRIBUTES ((DWORD)-1)
+# endif
+  /* Windows MoveFileEx may not replace read-only or in-use files.  If it
+     fails then remove the read-only attribute from any existing destination.
+     Try multiple times since we may be racing against another process
+     creating/opening the destination file just before our MoveFileEx.  */
+  int tries = 5;
+  while(!MoveFileEx(oldname, newname, MOVEFILE_REPLACE_EXISTING) && --tries)
+    {
+    DWORD attrs = GetFileAttributes(newname);
+    if((attrs != INVALID_FILE_ATTRIBUTES) &&
+       (attrs & FILE_ATTRIBUTE_READONLY))
+      {
+      // Remove the read-only attribute from the destination file.
       SetFileAttributes(newname, attrs & ~FILE_ATTRIBUTE_READONLY);
       }
-
-    /* Check the windows version number.  */
-    osv.dwOSVersionInfoSize = sizeof(osv);
-    GetVersionEx(&osv);
-    if(osv.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS)
-      {
-      /* This is Win9x.  There is no MoveFileEx implementation.  We
-         cannot quite rename the file atomically.  Just delete the
-         destination and then move the file.  */
-      DeleteFile(newname);
-      return MoveFile(oldname, newname) != 0;
-      }
     else
       {
-      /* This is not Win9x.  Use the MoveFileEx implementation.  */
-      return MoveFileEx(oldname, newname, MOVEFILE_REPLACE_EXISTING) != 0;
+      // The file may be temporarily in use so wait a bit.
+      cmSystemTools::Delay(100);
       }
     }
-  else
-    {
-    /* The destination does not exist.  Just move the file.  */
-    return MoveFile(oldname, newname) != 0;
-    }
+  return tries > 0;
 #else
   /* On UNIX we have an OS-provided call to do this atomically.  */
   return rename(oldname, newname) == 0;

-----------------------------------------------------------------------

Summary of changes:
 Source/cmSystemTools.cxx |   50 +++++++++++++++------------------------------
 1 files changed, 17 insertions(+), 33 deletions(-)


hooks/post-receive
-- 
CMake


More information about the Cmake-commits mailing list