Skip to content

Commit 1f46b6e

Browse files
committed
util: Work around libstdc++ create_directories issue
Work around libstdc++ issue [PR101510] with create_directories where the leaf already exists as a symlink. Fixes #24257, introduced by the switch to `std::filesystem`. It is meant to be more thorough than #24266, which only worked around one instance of the problem. The issue was fixed upstream in https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=124eaa50e0a34f5f89572c1aa812c50979da58fc, but unfortunately we'll have to carry a fix for it for a while. This introduces a function `fs::create_directories` which wraps `std::filesystem::create_directories`. This allows easiliy reverting the workaround when it is no longer necessary.
1 parent df08250 commit 1f46b6e

File tree

2 files changed

+24
-2
lines changed

2 files changed

+24
-2
lines changed

src/fs.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,28 @@ static inline path PathFromString(const std::string& string)
140140
return std::filesystem::path(string);
141141
#endif
142142
}
143+
144+
/**
145+
* Create directory (and if necessary its parents), unless the leaf directory
146+
* already exists or is a symlink to an existing directory.
147+
* This is a temporary workaround for an issue in libstdc++ that has been fixed
148+
* upstream [PR101510].
149+
*/
150+
static inline bool create_directories(const std::filesystem::path& p)
151+
{
152+
if (std::filesystem::is_symlink(p) && std::filesystem::is_directory(p)) {
153+
return false;
154+
}
155+
return std::filesystem::create_directories(p);
156+
}
157+
158+
/**
159+
* This variant is not used. Delete it to prevent it from accidentally working
160+
* around the workaround. If it is needed, add a workaround in the same pattern
161+
* as above.
162+
*/
163+
bool create_directories(const std::filesystem::path& p, std::error_code& ec) = delete;
164+
143165
} // namespace fs
144166

145167
/** Bridge operations to C stdio */

src/test/dbwrapper_tests.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,7 @@ BOOST_AUTO_TEST_CASE(existing_data_no_obfuscate)
203203
{
204204
// We're going to share this fs::path between two wrappers
205205
fs::path ph = m_args.GetDataDirBase() / "existing_data_no_obfuscate";
206-
create_directories(ph);
206+
fs::create_directories(ph);
207207

208208
// Set up a non-obfuscated wrapper to write some initial data.
209209
std::unique_ptr<CDBWrapper> dbw = std::make_unique<CDBWrapper>(ph, (1 << 10), false, false, false);
@@ -244,7 +244,7 @@ BOOST_AUTO_TEST_CASE(existing_data_reindex)
244244
{
245245
// We're going to share this fs::path between two wrappers
246246
fs::path ph = m_args.GetDataDirBase() / "existing_data_reindex";
247-
create_directories(ph);
247+
fs::create_directories(ph);
248248

249249
// Set up a non-obfuscated wrapper to write some initial data.
250250
std::unique_ptr<CDBWrapper> dbw = std::make_unique<CDBWrapper>(ph, (1 << 10), false, false, false);

0 commit comments

Comments
 (0)