diff options
author | gregorycu <gregory.currie@gmail.com> | 2016-05-01 17:27:29 +1000 |
---|---|---|
committer | Craig Robbins <kde.psych@gmail.com> | 2016-05-01 17:28:16 +1000 |
commit | c95734654caf1064907926978b2cbbc3601fdae9 (patch) | |
tree | d747b2781d55b861e64aeae1aae756fde92cebd2 /src | |
parent | 29877dfb4588c9a7fa4fb6321f625bcd8e0bcd84 (diff) | |
download | minetest-c95734654caf1064907926978b2cbbc3601fdae9.tar.gz minetest-c95734654caf1064907926978b2cbbc3601fdae9.tar.bz2 minetest-c95734654caf1064907926978b2cbbc3601fdae9.zip |
Use MoveFileEx to rename files on Windows (not rename)
Diffstat (limited to 'src')
-rw-r--r-- | src/filesys.cpp | 26 |
1 files changed, 21 insertions, 5 deletions
diff --git a/src/filesys.cpp b/src/filesys.cpp index 501f9ad6c..b4c52ab79 100644 --- a/src/filesys.cpp +++ b/src/filesys.cpp @@ -26,6 +26,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include <fstream> #include "log.h" #include "config.h" +#include "porting.h" namespace fs { @@ -698,22 +699,37 @@ bool safeWriteToFile(const std::string &path, const std::string &content) return false; } + bool rename_success = false; + // Move the finished temporary file over the real file #ifdef _WIN32 + // When creating the file, it can cause Windows Search indexer, virus scanners and other apps + // to query the file. This can make the move file call below fail. + // We retry up to 5 times, with a 1ms sleep between, before we consider the whole operation failed + int number_attempts = 0; + while (number_attempts < 5) { + rename_success = MoveFileEx(tmp_file.c_str(), path.c_str(), + MOVEFILE_REPLACE_EXISTING | MOVEFILE_WRITE_THROUGH); + if (rename_success) + break; + sleep_ms(1); + ++number_attempts; + } +#else // On POSIX compliant systems rename() is specified to be able to swap the // file in place of the destination file, making this a truly error-proof // transaction. - // However, on Windows, the target file has to be removed first. - remove(path.c_str()); + rename_success = rename(tmp_file.c_str(), path.c_str()) == 0; #endif - if(rename(tmp_file.c_str(), path.c_str())) { + if (!rename_success) { + warningstream << "Failed to write to file: " << path.c_str() << std::endl; // Remove the temporary file because moving it over the target file // failed. remove(tmp_file.c_str()); return false; - } else { - return true; } + + return true; } bool Rename(const std::string &from, const std::string &to) |