diff --git a/src/crystal/system/dir.cr b/src/crystal/system/dir.cr index c5f57a04b82e..33d983c8e411 100644 --- a/src/crystal/system/dir.cr +++ b/src/crystal/system/dir.cr @@ -7,13 +7,14 @@ module Crystal::System::Dir # In particular we only care about the name and whether its # a directory or not to improve the performance of Dir.glob # by avoid having to call File.info on every directory entry. + # If dir is nil, the type is unknown. # In the future we might change Dir's API to expose these entries # with more info but right now it's not necessary. struct Entry getter name getter? dir - def initialize(@name : String, @dir : Bool) + def initialize(@name : String, @dir : Bool?) end end diff --git a/src/crystal/system/unix/dir.cr b/src/crystal/system/unix/dir.cr index 843595ad7dcd..75d1b18fdb5a 100644 --- a/src/crystal/system/unix/dir.cr +++ b/src/crystal/system/unix/dir.cr @@ -13,7 +13,12 @@ module Crystal::System::Dir Errno.value = Errno::NONE if entry = LibC.readdir(dir) name = String.new(entry.value.d_name.to_unsafe) - dir = entry.value.d_type == LibC::DT_DIR + + dir = case entry.value.d_type + when LibC::DT_DIR then true + when LibC::DT_UNKNOWN then nil + else false + end Entry.new(name, dir) elsif Errno.value != Errno::NONE raise ::File::Error.from_errno("Error reading directory entries", file: path) diff --git a/src/dir/glob.cr b/src/dir/glob.cr index 05a4601057ae..99b648f6747a 100644 --- a/src/dir/glob.cr +++ b/src/dir/glob.cr @@ -171,10 +171,10 @@ class Dir fullpath = Path[path].join("").to_s end - if dir_entry - yield fullpath if dir_entry.dir? - else - yield fullpath if dir?(fullpath) + if dir_entry && !dir_entry.dir?.nil? + yield fullpath + elsif dir?(fullpath) + yield fullpath end in EntryMatch return if sequence[pos + 1]?.is_a?(RecursiveDirectories) @@ -187,8 +187,12 @@ class Dir each_child(path) do |entry| if cmd.matches?(entry.name) - if entry.dir? - fullpath = join(path, entry.name) + is_dir = entry.dir? + fullpath = join(path, entry.name) + if is_dir.nil? + is_dir = dir?(fullpath) + end + if is_dir path_stack << {next_pos, fullpath, entry} end end @@ -248,7 +252,12 @@ class Dir yield fullpath if next_cmd.matches?(entry.name) end - if entry.dir? + is_dir = entry.dir? + if is_dir.nil? + is_dir = dir?(fullpath) + end + + if is_dir path_stack << {next_pos, fullpath, entry} dir_path_stack.push fullpath diff --git a/src/lib_c/aarch64-linux-gnu/c/dirent.cr b/src/lib_c/aarch64-linux-gnu/c/dirent.cr index 3cb61b21129e..a6853d646279 100644 --- a/src/lib_c/aarch64-linux-gnu/c/dirent.cr +++ b/src/lib_c/aarch64-linux-gnu/c/dirent.cr @@ -3,7 +3,8 @@ require "./sys/types" lib LibC type DIR = Void - DT_DIR = 4 + DT_UNKNOWN = 0 + DT_DIR = 4 struct Dirent d_ino : InoT diff --git a/src/lib_c/aarch64-linux-musl/c/dirent.cr b/src/lib_c/aarch64-linux-musl/c/dirent.cr index c22a0a18666f..55662ab60f0e 100644 --- a/src/lib_c/aarch64-linux-musl/c/dirent.cr +++ b/src/lib_c/aarch64-linux-musl/c/dirent.cr @@ -3,7 +3,8 @@ require "./sys/types" lib LibC type DIR = Void - DT_DIR = 4 + DT_UNKNOWN = 0 + DT_DIR = 4 struct Dirent d_ino : InoT diff --git a/src/lib_c/arm-linux-gnueabihf/c/dirent.cr b/src/lib_c/arm-linux-gnueabihf/c/dirent.cr index 3cb61b21129e..a6853d646279 100644 --- a/src/lib_c/arm-linux-gnueabihf/c/dirent.cr +++ b/src/lib_c/arm-linux-gnueabihf/c/dirent.cr @@ -3,7 +3,8 @@ require "./sys/types" lib LibC type DIR = Void - DT_DIR = 4 + DT_UNKNOWN = 0 + DT_DIR = 4 struct Dirent d_ino : InoT diff --git a/src/lib_c/i386-linux-gnu/c/dirent.cr b/src/lib_c/i386-linux-gnu/c/dirent.cr index e4674e3bf0f4..714ccef24a19 100644 --- a/src/lib_c/i386-linux-gnu/c/dirent.cr +++ b/src/lib_c/i386-linux-gnu/c/dirent.cr @@ -3,7 +3,8 @@ require "./sys/types" lib LibC type DIR = Void - DT_DIR = 4 + DT_UNKNOWN = 0 + DT_DIR = 4 struct Dirent d_ino : InoT diff --git a/src/lib_c/i386-linux-musl/c/dirent.cr b/src/lib_c/i386-linux-musl/c/dirent.cr index c22a0a18666f..55662ab60f0e 100644 --- a/src/lib_c/i386-linux-musl/c/dirent.cr +++ b/src/lib_c/i386-linux-musl/c/dirent.cr @@ -3,7 +3,8 @@ require "./sys/types" lib LibC type DIR = Void - DT_DIR = 4 + DT_UNKNOWN = 0 + DT_DIR = 4 struct Dirent d_ino : InoT diff --git a/src/lib_c/x86_64-darwin/c/dirent.cr b/src/lib_c/x86_64-darwin/c/dirent.cr index 309689fa24f7..13f936e1042d 100644 --- a/src/lib_c/x86_64-darwin/c/dirent.cr +++ b/src/lib_c/x86_64-darwin/c/dirent.cr @@ -3,7 +3,8 @@ require "./sys/types" lib LibC type DIR = Void - DT_DIR = 4 + DT_UNKNOWN = 0 + DT_DIR = 4 struct Dirent d_ino : InoT diff --git a/src/lib_c/x86_64-dragonfly/c/dirent.cr b/src/lib_c/x86_64-dragonfly/c/dirent.cr index 51986d65e21c..044330a63b5d 100644 --- a/src/lib_c/x86_64-dragonfly/c/dirent.cr +++ b/src/lib_c/x86_64-dragonfly/c/dirent.cr @@ -3,7 +3,8 @@ require "./sys/types" lib LibC type DIR = Void - DT_DIR = 4 + DT_UNKNOWN = 0 + DT_DIR = 4 struct Dirent d_fileno : InoT diff --git a/src/lib_c/x86_64-freebsd/c/dirent.cr b/src/lib_c/x86_64-freebsd/c/dirent.cr index 0028289a3ced..bdad9169929f 100644 --- a/src/lib_c/x86_64-freebsd/c/dirent.cr +++ b/src/lib_c/x86_64-freebsd/c/dirent.cr @@ -3,7 +3,8 @@ require "./sys/types" lib LibC type DIR = Void - DT_DIR = 4 + DT_UNKNOWN = 0 + DT_DIR = 4 struct Dirent {% if flag?(:freebsd11) %} diff --git a/src/lib_c/x86_64-linux-gnu/c/dirent.cr b/src/lib_c/x86_64-linux-gnu/c/dirent.cr index 3cb61b21129e..a6853d646279 100644 --- a/src/lib_c/x86_64-linux-gnu/c/dirent.cr +++ b/src/lib_c/x86_64-linux-gnu/c/dirent.cr @@ -3,7 +3,8 @@ require "./sys/types" lib LibC type DIR = Void - DT_DIR = 4 + DT_UNKNOWN = 0 + DT_DIR = 4 struct Dirent d_ino : InoT diff --git a/src/lib_c/x86_64-linux-musl/c/dirent.cr b/src/lib_c/x86_64-linux-musl/c/dirent.cr index c22a0a18666f..55662ab60f0e 100644 --- a/src/lib_c/x86_64-linux-musl/c/dirent.cr +++ b/src/lib_c/x86_64-linux-musl/c/dirent.cr @@ -3,7 +3,8 @@ require "./sys/types" lib LibC type DIR = Void - DT_DIR = 4 + DT_UNKNOWN = 0 + DT_DIR = 4 struct Dirent d_ino : InoT diff --git a/src/lib_c/x86_64-netbsd/c/dirent.cr b/src/lib_c/x86_64-netbsd/c/dirent.cr index 4b3186ab6a97..78197bbc29c6 100644 --- a/src/lib_c/x86_64-netbsd/c/dirent.cr +++ b/src/lib_c/x86_64-netbsd/c/dirent.cr @@ -13,7 +13,8 @@ lib LibC dd_lock : Void* end - DT_DIR = 4 + DT_UNKNOWN = 0 + DT_DIR = 4 struct Dirent d_fileno : InoT diff --git a/src/lib_c/x86_64-openbsd/c/dirent.cr b/src/lib_c/x86_64-openbsd/c/dirent.cr index 125d64740e38..e332bd30c8f6 100644 --- a/src/lib_c/x86_64-openbsd/c/dirent.cr +++ b/src/lib_c/x86_64-openbsd/c/dirent.cr @@ -3,7 +3,8 @@ require "./sys/types" lib LibC type DIR = Void - DT_DIR = 4 + DT_UNKNOWN = 0 + DT_DIR = 4 struct Dirent d_fileno : InoT