From f96de0296023ef936d62191803ecb48622e6b085 Mon Sep 17 00:00:00 2001 From: Eric Fiselier Date: Mon, 23 Jul 2018 22:40:41 +0000 Subject: [PATCH] Recommit "Use possibly cached directory entry values when performing recursive directory iteration." The initial patch didn't correctly handle systems when the dirent struct didn't provide the d_type member. Specifically it set the cache to the incorrect state, and claimed it was partially populated. The updated version of this change correctly handles setting up the cache when the file type is not known (aka file_type::none). llvm-svn: 337765 --- libcxx/include/experimental/filesystem | 12 ++++++++++-- .../experimental/filesystem/directory_iterator.cpp | 7 ++++--- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/libcxx/include/experimental/filesystem b/libcxx/include/experimental/filesystem index 2ed3eecffea3..9699699c718b 100644 --- a/libcxx/include/experimental/filesystem +++ b/libcxx/include/experimental/filesystem @@ -2200,8 +2200,16 @@ private: static __cached_data __create_iter_result(file_type __ft) { __cached_data __data; __data.__type_ = __ft; - __data.__cache_type_ = - __ft == file_type::symlink ? _IterSymlink : _IterNonSymlink; + __data.__cache_type_ = [&]() { + switch (__ft) { + case file_type::none: + return _Empty; + case file_type::symlink: + return _IterSymlink; + default: + return _IterNonSymlink; + } + }(); return __data; } diff --git a/libcxx/src/experimental/filesystem/directory_iterator.cpp b/libcxx/src/experimental/filesystem/directory_iterator.cpp index a6f10d07565b..c95ebc8ac340 100644 --- a/libcxx/src/experimental/filesystem/directory_iterator.cpp +++ b/libcxx/src/experimental/filesystem/directory_iterator.cpp @@ -47,9 +47,10 @@ static file_type get_file_type(DirEntT *ent, int) { } return file_type::none; } + template static file_type get_file_type(DirEntT *ent, long) { - return file_type::unknown; + return file_type::none; } static pair @@ -359,13 +360,13 @@ bool recursive_directory_iterator::__try_recursion(error_code *ec) { bool skip_rec = false; error_code m_ec; if (!rec_sym) { - file_status st = curr_it.__entry_.symlink_status(m_ec); + file_status st(curr_it.__entry_.__get_sym_ft(&m_ec)); if (m_ec && status_known(st)) m_ec.clear(); if (m_ec || is_symlink(st) || !is_directory(st)) skip_rec = true; } else { - file_status st = curr_it.__entry_.status(m_ec); + file_status st(curr_it.__entry_.__get_ft(&m_ec)); if (m_ec && status_known(st)) m_ec.clear(); if (m_ec || !is_directory(st))