diff --git a/Userland/Libraries/LibCore/DirIterator.cpp b/Userland/Libraries/LibCore/DirIterator.cpp index ea64c4e38e..84fe5a5777 100644 --- a/Userland/Libraries/LibCore/DirIterator.cpp +++ b/Userland/Libraries/LibCore/DirIterator.cpp @@ -41,6 +41,13 @@ DirIterator::DirIterator(DirIterator&& other) other.m_dir = nullptr; } +static constexpr bool dirent_has_d_type = +#if defined(AK_OS_SOLARIS) || defined(AK_OS_HAIKU) + false; +#else + true; +#endif + bool DirIterator::advance_next() { if (!m_dir) @@ -58,23 +65,10 @@ bool DirIterator::advance_next() return false; } -#if defined(AK_OS_SOLARIS) || defined(AK_OS_HAIKU) - m_next = DirectoryEntry::from_stat(m_dir, *de); -#else - m_next = DirectoryEntry::from_dirent(*de); - - // dirent structures from readdir aren't guaranteed to contain valid file types, - // as it is possible that the underlying filesystem doesn't keep track of those. - if (m_next->type == DirectoryEntry::Type::Unknown && !m_next->name.is_empty()) { - struct stat statbuf; - if (fstatat(dirfd(m_dir), de->d_name, &statbuf, AT_SYMLINK_NOFOLLOW) < 0) { - m_error = Error::from_errno(errno); - dbgln("DirIteration error: {}", m_error.value()); - return false; - } - m_next->type = DirectoryEntry::directory_entry_type_from_stat(statbuf.st_mode); - } -#endif + if constexpr (dirent_has_d_type) + m_next = DirectoryEntry::from_dirent(*de); + else + m_next = DirectoryEntry::from_stat(m_dir, *de); if (m_next->name.is_empty()) return false; @@ -85,6 +79,20 @@ bool DirIterator::advance_next() if (m_flags & Flags::SkipParentAndBaseDir && (m_next->name == "." || m_next->name == "..")) continue; + if constexpr (dirent_has_d_type) { + // dirent structures from readdir aren't guaranteed to contain valid file types, + // as it is possible that the underlying filesystem doesn't keep track of those. + if (m_next->type == DirectoryEntry::Type::Unknown) { + struct stat statbuf; + if (fstatat(dirfd(m_dir), de->d_name, &statbuf, AT_SYMLINK_NOFOLLOW) < 0) { + m_error = Error::from_errno(errno); + dbgln("DirIteration error: {}", m_error.value()); + return false; + } + m_next->type = DirectoryEntry::directory_entry_type_from_stat(statbuf.st_mode); + } + } + return !m_next->name.is_empty(); } }