Fix error reported by recursive_dir_it for dangling symlinks.

This only affects POSIX platforms not supporting openat & co.

When the underlying directory iterator does not produce symlink status
during iteration, and the iterator points to a dangling symlink, the
recursive_directory_iterator increment would attempt to refresh file
statuses in the directory_entry. This would fail because the refresh
would query status in addition to symlink_status. This error was
wrongly reported to the caller if following symlinks was disabled for
the recursive iterator.

Fix this by only querying symlink_status. status is checked later,
if the iterator is configured to follow symlinks.
This commit is contained in:
Andrey Semashev
2025-12-25 02:25:36 +03:00
parent d8eca47d05
commit 6ebbda28f5
2 changed files with 10 additions and 7 deletions

View File

@@ -43,6 +43,7 @@
<h2>1.91.0</h2>
<ul>
<li>Due to a change in Boost.System, Boost.Filesystem now defines and uses its own platform macros <code>BOOST_FILESYSTEM_POSIX_API</code> and <code>BOOST_FILESYSTEM_WINDOWS_API</code>. These macros may not necessarily match the old <code>BOOST_POSIX_API</code> and <code>BOOST_WINDOWS_API</code> macros defined by Boost.System.</li>
<li>On POSIX platforms not supporting <code>openat</code> and related APIs, fixed an error reported by <code>recursive_directory_iterator</code> increment when the iterator encounters a dangling symlink and following symlinks is disabled.</li>
</ul>
<h2>1.90.0</h2>

View File

@@ -1487,7 +1487,7 @@ void recursive_directory_iterator_increment(recursive_directory_iterator& it, sy
if ((imp->m_options & directory_options::follow_directory_symlink) == directory_options::none ||
(imp->m_options & directory_options::skip_dangling_symlinks) != directory_options::none)
{
#if defined(BOOST_FILESYSTEM_POSIX_API) && defined(BOOST_FILESYSTEM_HAS_FDOPENDIR_NOFOLLOW) && defined(BOOST_FILESYSTEM_HAS_POSIX_AT_APIS)
#if defined(BOOST_FILESYSTEM_POSIX_API)
directory_iterator const& dir_it = imp->m_stack.back();
if (filesystem::type_present(dir_it->m_symlink_status))
{
@@ -1495,6 +1495,7 @@ void recursive_directory_iterator_increment(recursive_directory_iterator& it, sy
}
else
{
#if defined(BOOST_FILESYSTEM_HAS_FDOPENDIR_NOFOLLOW) && defined(BOOST_FILESYSTEM_HAS_POSIX_AT_APIS)
parentdir_fd = dir_itr_fd(*dir_it.m_imp, ec);
if (ec)
return result;
@@ -1504,8 +1505,13 @@ void recursive_directory_iterator_increment(recursive_directory_iterator& it, sy
symlink_ft = detail::symlink_status_impl(dir_it_filename, &ec, parentdir_fd).type();
if (ec)
return result;
#else // defined(BOOST_FILESYSTEM_HAS_FDOPENDIR_NOFOLLOW) && defined(BOOST_FILESYSTEM_HAS_POSIX_AT_APIS)
symlink_ft = detail::symlink_status_impl(dir_it->path(), &ec).type();
if (ec)
return result;
#endif // defined(BOOST_FILESYSTEM_HAS_FDOPENDIR_NOFOLLOW) && defined(BOOST_FILESYSTEM_HAS_POSIX_AT_APIS)
}
#elif defined(BOOST_FILESYSTEM_WINDOWS_API)
#else // defined(BOOST_FILESYSTEM_POSIX_API)
directory_iterator const& dir_it = imp->m_stack.back();
if (filesystem::type_present(dir_it->m_symlink_status))
{
@@ -1544,11 +1550,7 @@ void recursive_directory_iterator_increment(recursive_directory_iterator& it, sy
if (ec)
return result;
}
#else
symlink_ft = imp->m_stack.back()->symlink_file_type(ec);
if (ec)
return result;
#endif
#endif // defined(BOOST_FILESYSTEM_POSIX_API)
}
// Logic for following predicate was contributed by Daniel Aarno to handle cyclic