Add symlink handling tests and fix recursive_directory_iterator behavior with symlinks (refs #178)

This commit is contained in:
Steffen Schümann 2026-07-12 20:53:20 +02:00
parent 73212968f6
commit 09540bf5e7
3 changed files with 20 additions and 2 deletions

View File

@ -669,6 +669,8 @@ to the expected behavior.
`last_write_time()` now consistently follows symlinks.
* Fix for [#208](https://github.com/gulrak/filesystem/issues/208), filesystem
metadata now preserves subsecond modification times.
* Fix for [#178](https://github.com/gulrak/filesystem/issues/178), recursive
iteration no longer resolves symlinks unless requested.
* Fix for [#185](https://github.com/gulrak/filesystem/issues/185),
`lexically_normal()` now preserves unresolved parent components in relative
paths.

View File

@ -6047,12 +6047,13 @@ GHC_INLINE recursive_directory_iterator& recursive_directory_iterator::operator+
GHC_INLINE recursive_directory_iterator& recursive_directory_iterator::increment(std::error_code& ec) noexcept
{
bool isSymLink = (*this)->is_symlink(ec);
bool isDir = !ec && (*this)->is_directory(ec);
const bool followSymlink = (options() & directory_options::follow_directory_symlink) != directory_options::none;
bool isDir = !ec && (!isSymLink || followSymlink) && (*this)->is_directory(ec);
if (isSymLink && detail::is_not_found_error(ec)) {
ec.clear();
}
if (!ec) {
if (recursion_pending() && isDir && (!isSymLink || (options() & directory_options::follow_directory_symlink) != directory_options::none)) {
if (recursion_pending() && isDir) {
_impl->_dir_iter_stack.push(directory_iterator((*this)->path(), _impl->_options, ec));
}
else {

View File

@ -1681,6 +1681,21 @@ TEST_CASE("fs.class.rec.dir.itr - class recursive_directory_iterator", "[filesys
}
CHECK(os.str() == "d2/b,d2/ds1,d2/ds2,");
}
if (is_symlink_creation_supported()) {
TemporaryDirectory t(TempOpt::change_path);
generateFile("regular");
fs::create_symlink("self", "self");
std::multiset<std::string> result;
REQUIRE_NOTHROW([&]() {
for (const auto& de : fs::recursive_directory_iterator(".")) {
result.insert(de.path().generic_string());
}
}());
CHECK(result.size() == 2);
CHECK(result.count("./regular") == 1);
CHECK(result.count("./self") == 1);
CHECK(fs::remove("self"));
}
}
TEST_CASE("fs.op.absolute - absolute", "[filesystem][operations][fs.op.absolute]")