Skip to content

Commit 6b4cf07

Browse files
committed
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.
1 parent 407d2f1 commit 6b4cf07

1 file changed

Lines changed: 22 additions & 8 deletions

File tree

engine/system/win/sys_main.cpp

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -214,10 +214,17 @@ bool find_c::FindFirst(std::filesystem::path const&& fileSpec)
214214
auto candFilename = iter->path().filename();
215215
if (GlobMatch(globPattern, candFilename)) {
216216
fileName = candFilename;
217-
isDirectory = iter->is_directory();
218-
fileSize = iter->file_size();
219-
auto mod = iter->last_write_time();
220-
modified = mod.time_since_epoch().count();
217+
// Query metadata through the error_code overloads. The throwing overloads
218+
// abort whenever status() fails on an entry, and outside of Windows (where
219+
// file_size() reports the cached 0 for directories) file_size() always fails
220+
// on a directory, which would take down every search over a folder tree.
221+
std::error_code entEc;
222+
isDirectory = iter->is_directory(entEc);
223+
fileSize = isDirectory ? 0 : iter->file_size(entEc);
224+
auto mod = iter->last_write_time(entEc);
225+
// A failed query yields file_time_type::min(), whose negative count would
226+
// wrap to a huge timestamp and sort the entry to the top of "Last Edited".
227+
modified = entEc ? 0 : mod.time_since_epoch().count();
221228
return true;
222229
}
223230
}
@@ -234,10 +241,17 @@ bool find_c::FindNext()
234241
auto candFilename = iter->path().filename();
235242
if (GlobMatch(globPattern, candFilename)) {
236243
fileName = candFilename;
237-
isDirectory = iter->is_directory();
238-
fileSize = iter->file_size();
239-
auto mod = iter->last_write_time();
240-
modified = mod.time_since_epoch().count();
244+
// Query metadata through the error_code overloads. The throwing overloads
245+
// abort whenever status() fails on an entry, and outside of Windows (where
246+
// file_size() reports the cached 0 for directories) file_size() always fails
247+
// on a directory, which would take down every search over a folder tree.
248+
std::error_code entEc;
249+
isDirectory = iter->is_directory(entEc);
250+
fileSize = isDirectory ? 0 : iter->file_size(entEc);
251+
auto mod = iter->last_write_time(entEc);
252+
// A failed query yields file_time_type::min(), whose negative count would
253+
// wrap to a huge timestamp and sort the entry to the top of "Last Edited".
254+
modified = entEc ? 0 : mod.time_since_epoch().count();
241255
return true;
242256
}
243257
}

0 commit comments

Comments
 (0)