| 324 | } |
| 325 | |
| 326 | bool IsDirWritable(const fs::path& dir_path) |
| 327 | { |
| 328 | // Attempt to create a tmp file in the directory |
| 329 | if (!fs::is_directory(dir_path)) throw std::runtime_error(strprintf("Path %s is not a directory", fs::PathToString(dir_path))); |
| 330 | FastRandomContext rng; |
| 331 | const auto tmp = dir_path / fs::PathFromString(strprintf(".tmp_%d", rng.rand64())); |
| 332 | |
| 333 | const char* mode; |
| 334 | #ifdef __MINGW64__ |
| 335 | mode = "w"; // Temporary workaround for https://github.com/bitcoin/bitcoin/issues/30210 |
| 336 | #else |
| 337 | mode = "wx"; |
| 338 | #endif |
| 339 | |
| 340 | if (const auto created{fsbridge::fopen(tmp, mode)}) { |
| 341 | std::fclose(created); |
| 342 | std::error_code ec; |
| 343 | fs::remove(tmp, ec); // clean up, ignore errors |
| 344 | return true; |
| 345 | } |
| 346 | return false; |
| 347 | } |
| 348 | |
| 349 | #ifdef __APPLE__ |
| 350 | FSType GetFilesystemType(const fs::path& path) |
no test coverage detected