aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorlaanwj <126646+laanwj@users.noreply.github.com>2022-02-17 12:29:22 +0100
committerlaanwj <126646+laanwj@users.noreply.github.com>2022-02-17 12:29:41 +0100
commitdf0825046acc7cb496c47666e36af18118beb030 (patch)
tree50cea66b90f0bbbb877184f0086c3a6939b8e4d7 /src
parent97611921bed83ff4779cf4827bd0e51a321df4b5 (diff)
parentdc01cbc538765f64326bca30952c83e3862d0d54 (diff)
downloadbitcoin-df0825046acc7cb496c47666e36af18118beb030.tar.xz
Merge bitcoin/bitcoin#24331: util: Revert back `MoveFileExW` call for MinGW-w64
dc01cbc538765f64326bca30952c83e3862d0d54 test: Add fs_tests/rename unit test (Hennadii Stepanov) d4999d40b9bd04dc20111aaaa6ed2d3db1a5caf9 util: Revert back MoveFileExW call for MinGW-w64 (Hennadii Stepanov) Pull request description: Unfortunately, bitcoin/bitcoin#24308 introduced a [regression](https://github.com/bitcoin/bitcoin/pull/24308#issuecomment-1037259386) for mingw builds. The root of the problem is a broken implementation of [`std::filesystem::rename`](https://en.cppreference.com/w/cpp/filesystem/rename). In particular, the expected behavior > If `old_p` is a non-directory file, then `new_p` must be ... existing non-directory file: `new_p` _is first deleted_... fails with the "File exists" error. This PR reverts back the `MoveFileExW` call, and adds the [suggested](https://github.com/bitcoin/bitcoin/pull/24308#pullrequestreview-878832906) unit test. ACKs for top commit: vasild: ACK dc01cbc538765f64326bca30952c83e3862d0d54 Tree-SHA512: c8e5a98844cfa32bec0ad67a1aaa58fe2efd0c5474d3e83490211985b110f83245758a742dcaa0a933a192ab66a7f11807e0c53ae69260b7dd02fc99f6d03849
Diffstat (limited to 'src')
-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
}
/**