summaryrefslogtreecommitdiff
path: root/src/filesys.cpp
diff options
context:
space:
mode:
authorPerttu Ahola <celeron55@gmail.com>2016-01-01 18:14:30 +0200
committerPerttu Ahola <celeron55@gmail.com>2016-01-01 18:21:18 +0200
commit64c060e1f2d94d8277246d8cdd8a886010564770 (patch)
treec7b557b57acfe43bf8e65c7058a9e2efc0797809 /src/filesys.cpp
parent43c804a00b5f6177d0bb02404804234606197dc5 (diff)
downloadminetest-64c060e1f2d94d8277246d8cdd8a886010564770.tar.gz
minetest-64c060e1f2d94d8277246d8cdd8a886010564770.tar.bz2
minetest-64c060e1f2d94d8277246d8cdd8a886010564770.zip
filesys: safeWriteToFile(): Remove the target file before rename only on Windows
Removing the target file on other platforms was enabled likely unintentionally by commit 5f1f1151d3a9c113902630adc16cc3f4845da7ba. This may be the reason why there has been corruption of files on Linux on hard shutdowns. Previously I described the problem and this fix in issue #3084.
Diffstat (limited to 'src/filesys.cpp')
-rw-r--r--src/filesys.cpp11
1 files changed, 10 insertions, 1 deletions
diff --git a/src/filesys.cpp b/src/filesys.cpp
index 5fdc97634..501f9ad6c 100644
--- a/src/filesys.cpp
+++ b/src/filesys.cpp
@@ -693,13 +693,22 @@ bool safeWriteToFile(const std::string &path, const std::string &content)
os.flush();
os.close();
if (os.fail()) {
+ // Remove the temporary file because writing it failed and it's useless.
remove(tmp_file.c_str());
return false;
}
- // Copy file
+ // Move the finished temporary file over the real file
+#ifdef _WIN32
+ // 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());
+#endif
if(rename(tmp_file.c_str(), path.c_str())) {
+ // Remove the temporary file because moving it over the target file
+ // failed.
remove(tmp_file.c_str());
return false;
} else {