diff --git a/include/ghc/filesystem.hpp b/include/ghc/filesystem.hpp index 6cbc892..bcef500 100644 --- a/include/ghc/filesystem.hpp +++ b/include/ghc/filesystem.hpp @@ -595,6 +595,7 @@ private: friend void swap(path& lhs, path& rhs) noexcept; friend size_t hash_value(const path& p) noexcept; friend path canonical(const path& p, std::error_code& ec); + friend bool create_directories(const path& p, std::error_code& ec) noexcept; string_type::size_type root_name_length() const noexcept; void postprocess_path_with_format(format fmt); void check_long_path(); @@ -3900,35 +3901,36 @@ GHC_INLINE bool create_directories(const path& p, std::error_code& ec) noexcept path current; ec.clear(); bool didCreate = false; - for (path::string_type part : p) { + auto rootPathLen = p._prefixLength + p.root_name_length() + (p.has_root_directory() ? 1 : 0); + current = p.native().substr(0, rootPathLen); + path folders(p._path.substr(rootPathLen)); + for (path::string_type part : folders) { current /= part; - if (current != p.root_name() && current != p.root_path()) { - std::error_code tec; - auto fs = status(current, tec); - if (tec && fs.type() != file_type::not_found) { - ec = tec; - return false; - } - if (!exists(fs)) { - create_directory(current, ec); - if (ec) { - std::error_code tmp_ec; - if (is_directory(current, tmp_ec)) { - ec.clear(); - } - else { - return false; - } - } - didCreate = true; - } -#ifndef LWG_2935_BEHAVIOUR - else if (!is_directory(fs)) { - ec = detail::make_error_code(detail::portable_error::exists); - return false; - } -#endif + std::error_code tec; + auto fs = status(current, tec); + if (tec && fs.type() != file_type::not_found) { + ec = tec; + return false; } + if (!exists(fs)) { + create_directory(current, ec); + if (ec) { + std::error_code tmp_ec; + if (is_directory(current, tmp_ec)) { + ec.clear(); + } + else { + return false; + } + } + didCreate = true; + } +#ifndef LWG_2935_BEHAVIOUR + else if (!is_directory(fs)) { + ec = detail::make_error_code(detail::portable_error::exists); + return false; + } +#endif } return didCreate; } diff --git a/test/filesystem_test.cpp b/test/filesystem_test.cpp index 32941bf..0eb5b81 100644 --- a/test/filesystem_test.cpp +++ b/test/filesystem_test.cpp @@ -2854,13 +2854,15 @@ TEST_CASE("Windows: Long filename support", "[filesystem][path][fs.path.win.long CHECK_NOTHROW(fs::create_directory(dir)); CHECK(fs::exists(dir)); generateFile(dir / "f0"); - CHECK(fs::exists(dir / "f0")); - auto native = dir.u8string(); - if (native.substr(0, 4) == u8"\\\\?\\") { - break; - } + REQUIRE(fs::exists(dir / "f0")); } - CHECK(c <= 'Z'); + CHECK(c > 'Z'); + fs::remove_all(fs::current_path() / std::string(16, 'A')); + CHECK(!fs::exists(fs::current_path() / std::string(16, 'A'))); + CHECK_NOTHROW(fs::create_directories(dir)); + CHECK(fs::exists(dir)); + generateFile(dir / "f0"); + CHECK(fs::exists(dir / "f0")); #else WARN("Windows specific tests are empty on non-Windows systems."); #endif