From 6b4cf071b73ea0169ddc698d5ada0005293dc7d1 Mon Sep 17 00:00:00 2001 From: oat Date: Sat, 25 Jul 2026 16:19:38 +0700 Subject: [PATCH] Stop find_c aborting on directory entries directory_entry::file_size() has no defined result for a directory. MSVC returns the size cached by FindFirstFile (0), so on Windows the throwing overloads used here never fire; libc++ calls stat and throws instead, so on macOS every NewFileSearch over a folder that contains a subdirectory died with "filesystem error: in file_size: Is a directory" before the binding could even apply its findDirectories filter. The build list was the visible casualty - one sub-folder under Builds/ made the startup screen unreachable - but Main.lua's folder copy/delete walks and the Export scripts glob directories the same way. Query the entry through the error_code overloads and report 0 for a directory, matching what Windows already returns. is_directory() and last_write_time() get the same treatment: they fail out of the same status() call, so an unreadable or dangling entry took the process down by the identical route. --- engine/system/win/sys_main.cpp | 30 ++++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/engine/system/win/sys_main.cpp b/engine/system/win/sys_main.cpp index 974e34d..e35c03c 100644 --- a/engine/system/win/sys_main.cpp +++ b/engine/system/win/sys_main.cpp @@ -214,10 +214,17 @@ bool find_c::FindFirst(std::filesystem::path const&& fileSpec) auto candFilename = iter->path().filename(); if (GlobMatch(globPattern, candFilename)) { fileName = candFilename; - isDirectory = iter->is_directory(); - fileSize = iter->file_size(); - auto mod = iter->last_write_time(); - modified = mod.time_since_epoch().count(); + // Query metadata through the error_code overloads. The throwing overloads + // abort whenever status() fails on an entry, and outside of Windows (where + // file_size() reports the cached 0 for directories) file_size() always fails + // on a directory, which would take down every search over a folder tree. + std::error_code entEc; + isDirectory = iter->is_directory(entEc); + fileSize = isDirectory ? 0 : iter->file_size(entEc); + auto mod = iter->last_write_time(entEc); + // A failed query yields file_time_type::min(), whose negative count would + // wrap to a huge timestamp and sort the entry to the top of "Last Edited". + modified = entEc ? 0 : mod.time_since_epoch().count(); return true; } } @@ -234,10 +241,17 @@ bool find_c::FindNext() auto candFilename = iter->path().filename(); if (GlobMatch(globPattern, candFilename)) { fileName = candFilename; - isDirectory = iter->is_directory(); - fileSize = iter->file_size(); - auto mod = iter->last_write_time(); - modified = mod.time_since_epoch().count(); + // Query metadata through the error_code overloads. The throwing overloads + // abort whenever status() fails on an entry, and outside of Windows (where + // file_size() reports the cached 0 for directories) file_size() always fails + // on a directory, which would take down every search over a folder tree. + std::error_code entEc; + isDirectory = iter->is_directory(entEc); + fileSize = isDirectory ? 0 : iter->file_size(entEc); + auto mod = iter->last_write_time(entEc); + // A failed query yields file_time_type::min(), whose negative count would + // wrap to a huge timestamp and sort the entry to the top of "Last Edited". + modified = entEc ? 0 : mod.time_since_epoch().count(); return true; } }