From d3363beb2f5b4bedee95aae6f6697f059ed3f48b Mon Sep 17 00:00:00 2001 From: Brad King Date: Wed, 15 Apr 2009 09:57:57 -0400 Subject: ENH: Move RenameFile to cmSystemTools This moves the cmGeneratedFileStream::RenameFile method implementation into cmSystemTools. It works only within a single filesystem volume, but is atomic when the operating system permits. --- Source/cmGeneratedFileStream.cxx | 54 +--------------------------------------- Source/cmSystemTools.cxx | 50 +++++++++++++++++++++++++++++++++++++ Source/cmSystemTools.h | 4 +++ 3 files changed, 55 insertions(+), 53 deletions(-) diff --git a/Source/cmGeneratedFileStream.cxx b/Source/cmGeneratedFileStream.cxx index 1bd8669..0a7bab0 100644 --- a/Source/cmGeneratedFileStream.cxx +++ b/Source/cmGeneratedFileStream.cxx @@ -18,14 +18,6 @@ #include "cmSystemTools.h" -// Includes needed for implementation of RenameFile. This is not in -// system tools because it is not implemented robustly enough to move -// files across directories. -#ifdef _WIN32 -# include -# include -#endif - #if defined(CMAKE_BUILD_WITH_CMAKE) # include #endif @@ -254,51 +246,7 @@ int cmGeneratedFileStreamBase::CompressFile(const char*, const char*) int cmGeneratedFileStreamBase::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) - { - 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); - } - else - { - /* This is not Win9x. Use the MoveFileEx implementation. */ - return MoveFileEx(oldname, newname, MOVEFILE_REPLACE_EXISTING); - } - } - else - { - /* The destination does not exist. Just move the file. */ - return MoveFile(oldname, newname); - } -#else - /* On UNIX we have an OS-provided call to do this atomically. */ - return rename(oldname, newname) == 0; -#endif + return cmSystemTools::RenameFile(oldname, newname); } //---------------------------------------------------------------------------- diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx index 84ed729..4fb9afa 100644 --- a/Source/cmSystemTools.cxx +++ b/Source/cmSystemTools.cxx @@ -1108,6 +1108,56 @@ bool cmSystemTools::CopyFileIfDifferent(const char* source, return Superclass::CopyFileIfDifferent(source, destination); } +//---------------------------------------------------------------------------- +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) + { + 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); + } + else + { + /* This is not Win9x. Use the MoveFileEx implementation. */ + return MoveFileEx(oldname, newname, MOVEFILE_REPLACE_EXISTING); + } + } + else + { + /* The destination does not exist. Just move the file. */ + return MoveFile(oldname, newname); + } +#else + /* On UNIX we have an OS-provided call to do this atomically. */ + return rename(oldname, newname) == 0; +#endif +} + bool cmSystemTools::ComputeFileMD5(const char* source, char* md5out) { #if defined(CMAKE_BUILD_WITH_CMAKE) diff --git a/Source/cmSystemTools.h b/Source/cmSystemTools.h index 8e639ac..7c6e3e9 100644 --- a/Source/cmSystemTools.h +++ b/Source/cmSystemTools.h @@ -166,6 +166,10 @@ public: static bool CopyFileIfDifferent(const char* source, const char* destination); + /** Rename a file or directory within a single disk volume (atomic + if possible). */ + static bool RenameFile(const char* oldname, const char* newname); + ///! Compute the md5sum of a file static bool ComputeFileMD5(const char* source, char* md5out); -- cgit v0.12