[committed] libstdc++: Reset filesystem::recursive_directory_iterator on error
Jonathan Wakely
jwakely@redhat.com
Wed Feb 2 00:09:07 GMT 2022
On Tue, 1 Feb 2022 at 22:00, Jonathan Wakely via Libstdc++
<libstdc++@gcc.gnu.org> wrote:
>
> The standard requires directory iterators to become equal to the end
> iterator value if they report an error. Some members functions of
> filesystem::recursive_directory_iterator fail to do that.
>
> libstdc++-v3/ChangeLog:
>
> * src/c++17/fs_dir.cc (recursive_directory_iterator::increment):
> Reset state to past-the-end iterator on error.
> (fs::recursive_directory_iterator::pop(error_code&)): Likewise.
> (fs::recursive_directory_iterator::pop()): Check _M_dirs before
> it might get reset.
> * src/filesystem/dir.cc (recursive_directory_iterator): Likewise,
> for the TS implementation.
> * testsuite/27_io/filesystem/iterators/error_reporting.cc: New test.
> * testsuite/experimental/filesystem/iterators/error_reporting.cc: New test.
> ---
> libstdc++-v3/src/c++17/fs_dir.cc | 12 +-
> libstdc++-v3/src/filesystem/dir.cc | 12 +-
> .../filesystem/iterators/error_reporting.cc | 135 +++++++++++++++++
> .../filesystem/iterators/error_reporting.cc | 136 ++++++++++++++++++
> 4 files changed, 291 insertions(+), 4 deletions(-)
> create mode 100644 libstdc++-v3/testsuite/27_io/filesystem/iterators/error_reporting.cc
> create mode 100644 libstdc++-v3/testsuite/experimental/filesystem/iterators/error_reporting.cc
>
[...]
> +
> +extern "C" struct dirent* readdir(DIR*)
> +{
> + switch (choice)
> + {
> + case 1:
> + global_dirent.d_ino = 999;
> + global_dirent.d_type = DT_REG;
These new tests should not use the d_type member unless it's actually
present on the OS. Fixed by the attached patch.
Tested x86_64-linux and mingw-w64, pushed to trunk.
-------------- next part --------------
commit d98668eb06f532b2dbe0c721fa1b9ed6e643df27
Author: Jonathan Wakely <jwakely@redhat.com>
Date: Tue Feb 1 23:58:08 2022
libstdc++: Do not use dirent::d_type unconditionally
These new tests should not use the d_type member unless it's actually
present on the OS.
libstdc++-v3/ChangeLog:
* testsuite/27_io/filesystem/iterators/error_reporting.cc: Use
autoconf macro to check whether d_type is present.
* testsuite/experimental/filesystem/iterators/error_reporting.cc:
Likewise.
diff --git a/libstdc++-v3/testsuite/27_io/filesystem/iterators/error_reporting.cc b/libstdc++-v3/testsuite/27_io/filesystem/iterators/error_reporting.cc
index 81ef1069367..1f297a731a3 100644
--- a/libstdc++-v3/testsuite/27_io/filesystem/iterators/error_reporting.cc
+++ b/libstdc++-v3/testsuite/27_io/filesystem/iterators/error_reporting.cc
@@ -36,14 +36,18 @@ extern "C" struct dirent* readdir(DIR*)
{
case 1:
global_dirent.d_ino = 999;
+#if defined _GLIBCXX_HAVE_STRUCT_DIRENT_D_TYPE && defined DT_REG
global_dirent.d_type = DT_REG;
+#endif
global_dirent.d_reclen = 0;
std::char_traits<char>::copy(global_dirent.d_name, "file", 5);
choice = 0;
return &global_dirent;
case 2:
global_dirent.d_ino = 111;
+#if defined _GLIBCXX_HAVE_STRUCT_DIRENT_D_TYPE && defined DT_DIR
global_dirent.d_type = DT_DIR;
+#endif
global_dirent.d_reclen = 60;
std::char_traits<char>::copy(global_dirent.d_name, "subdir", 7);
choice = 1;
diff --git a/libstdc++-v3/testsuite/experimental/filesystem/iterators/error_reporting.cc b/libstdc++-v3/testsuite/experimental/filesystem/iterators/error_reporting.cc
index ade62732028..806c511ebef 100644
--- a/libstdc++-v3/testsuite/experimental/filesystem/iterators/error_reporting.cc
+++ b/libstdc++-v3/testsuite/experimental/filesystem/iterators/error_reporting.cc
@@ -37,14 +37,18 @@ extern "C" struct dirent* readdir(DIR*)
{
case 1:
global_dirent.d_ino = 999;
+#if defined _GLIBCXX_HAVE_STRUCT_DIRENT_D_TYPE && defined DT_REG
global_dirent.d_type = DT_REG;
+#endif
global_dirent.d_reclen = 0;
std::char_traits<char>::copy(global_dirent.d_name, "file", 5);
choice = 0;
return &global_dirent;
case 2:
global_dirent.d_ino = 111;
+#if defined _GLIBCXX_HAVE_STRUCT_DIRENT_D_TYPE && defined DT_DIR
global_dirent.d_type = DT_DIR;
+#endif
global_dirent.d_reclen = 60;
std::char_traits<char>::copy(global_dirent.d_name, "subdir", 7);
choice = 1;
More information about the Libstdc++
mailing list