From 526b7e3b1b7746389aa399c2443c70e5e1cf24e7 Mon Sep 17 00:00:00 2001
From: Fabian Boehm <FHomborg@gmail.com>
Date: Tue, 12 Jul 2022 16:50:00 +0200
Subject: [PATCH] readdir_for_dirs: Actually filter out non-dirs

This function is supposed to return "the next directory". Because this
is imperfect, it only tries to.

Except it went to all the trouble of figuring out the type and then
just... returned it anyway.

This has nice speedups in globs with directory components like `*/` or
`**`. I have observed 1.1x to 2.0x.

We could also return when we know it's definitely a directory and then
skip a stat() later, but preliminary testing seemed to show that's not
worth much.
---
 src/wutil.cpp | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/src/wutil.cpp b/src/wutil.cpp
index 21ec26d6f..677e77cb3 100644
--- a/src/wutil.cpp
+++ b/src/wutil.cpp
@@ -96,6 +96,10 @@ bool wreaddir(DIR *dir, wcstring &out_name) {
     return true;
 }
 
+/// Wrapper for readdir that tries to only return directories.
+/// This is only supported on some (file)systems,
+/// and includes links,
+/// so the caller still needs to check.
 bool readdir_for_dirs(DIR *dir, std::string *out_name) {
     struct dirent *result = nullptr;
     while (!result) {
@@ -110,7 +114,9 @@ bool readdir_for_dirs(DIR *dir, std::string *out_name) {
                 break;  // these may be directories
             }
             default: {
-                break;  // nothing else can
+                // these definitely aren't - skip
+                result = nullptr;
+                continue;
             }
         }
 #else