On 24/10/16 17:50 +0100, Jonathan Wakely wrote:
Make directory iterators become end iterator on error * src/filesystem/dir.cc (open_dir): Return same value for errors whether ignored or not. (_Dir::advance(error_code*, directory_options)): Return false on error. (directory_iterator(const path&, directory_options, error_code*)): Create end iterator on error (LWG 2723). (recursive_directory_iterator(const path&, directory_options, error_code*)): Likewise. * testsuite/experimental/filesystem/iterators/directory_iterator.cc: Update expected behaviour on error. * testsuite/experimental/filesystem/iterators/ recursive_directory_iterator.cc: Likewise.
I missed the case where recursing into a sub-directory fails, and that happened to be the one bit of the test where I didn't add a new check. Tested x86_64-linux, committed to trunk.
commit a38bbf551b4f49e47fe1da03b779edba66240d5f Author: Jonathan Wakely <jwak...@redhat.com> Date: Wed Oct 26 13:34:15 2016 +0100 Fix error handling in recursive_directory_iterator::increment * src/filesystem/dir.cc (recursive_directory_iterator::increment): Reset state on error. * testsuite/experimental/filesystem/iterators/ recursive_directory_iterator.cc: Check state after increment error. diff --git a/libstdc++-v3/src/filesystem/dir.cc b/libstdc++-v3/src/filesystem/dir.cc index 4640d75..bcd7dd0 100644 --- a/libstdc++-v3/src/filesystem/dir.cc +++ b/libstdc++-v3/src/filesystem/dir.cc @@ -343,7 +343,10 @@ fs::recursive_directory_iterator::increment(error_code& ec) noexcept { _Dir dir = open_dir(top.entry.path(), _M_options, &ec); if (ec) - return *this; + { + _M_dirs.reset(); + return *this; + } if (dir.dirp) _M_dirs->push(std::move(dir)); } diff --git a/libstdc++-v3/testsuite/experimental/filesystem/iterators/recursive_directory_iterator.cc b/libstdc++-v3/testsuite/experimental/filesystem/iterators/recursive_directory_iterator.cc index b41c394..79aa178 100644 --- a/libstdc++-v3/testsuite/experimental/filesystem/iterators/recursive_directory_iterator.cc +++ b/libstdc++-v3/testsuite/experimental/filesystem/iterators/recursive_directory_iterator.cc @@ -81,6 +81,7 @@ test01() VERIFY( iter->path() == p/"d1/d2" ); iter.increment(ec); // should fail to recurse into p/d1/d2 VERIFY( ec ); + VERIFY( iter == fs::recursive_directory_iterator() ); // Test inaccessible sub-directory, skipping permission denied. iter = fs::recursive_directory_iterator(p, opts, ec);