aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/test/fs_tests.cpp36
-rw-r--r--src/util/system.cpp11
2 files changed, 46 insertions, 1 deletions
diff --git a/src/test/fs_tests.cpp b/src/test/fs_tests.cpp
index 1256395849..4fb2c23d98 100644
--- a/src/test/fs_tests.cpp
+++ b/src/test/fs_tests.cpp
@@ -118,4 +118,38 @@ BOOST_AUTO_TEST_CASE(fsbridge_fstream)
}
}
-BOOST_AUTO_TEST_SUITE_END() \ No newline at end of file
+BOOST_AUTO_TEST_CASE(rename)
+{
+ const fs::path tmpfolder{m_args.GetDataDirBase()};
+
+ const fs::path path1{GetUniquePath(tmpfolder)};
+ const fs::path path2{GetUniquePath(tmpfolder)};
+
+ const std::string path1_contents{"1111"};
+ const std::string path2_contents{"2222"};
+
+ {
+ std::ofstream file{path1};
+ file << path1_contents;
+ }
+
+ {
+ std::ofstream file{path2};
+ file << path2_contents;
+ }
+
+ // Rename path1 -> path2.
+ BOOST_CHECK(RenameOver(path1, path2));
+
+ BOOST_CHECK(!fs::exists(path1));
+
+ {
+ std::ifstream file{path2};
+ std::string contents;
+ file >> contents;
+ BOOST_CHECK_EQUAL(contents, path1_contents);
+ }
+ fs::remove(path2);
+}
+
+BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/util/system.cpp b/src/util/system.cpp
index 5cef2be07a..69811a751b 100644
--- a/src/util/system.cpp
+++ b/src/util/system.cpp
@@ -1062,9 +1062,20 @@ void ArgsManager::LogArgs() const
bool RenameOver(fs::path src, fs::path dest)
{
+#ifdef __MINGW64__
+ // This is a workaround for a bug in libstdc++ which
+ // implements std::filesystem::rename with _wrename function.
+ // This bug has been fixed in upstream:
+ // - GCC 10.3: 8dd1c1085587c9f8a21bb5e588dfe1e8cdbba79e
+ // - GCC 11.1: 1dfd95f0a0ca1d9e6cbc00e6cbfd1fa20a98f312
+ // For more details see the commits mentioned above.
+ return MoveFileExW(src.wstring().c_str(), dest.wstring().c_str(),
+ MOVEFILE_REPLACE_EXISTING) != 0;
+#else
std::error_code error;
fs::rename(src, dest, error);
return !error;
+#endif
}
/**