From 11cf91bc93b927a4d9f5c5af3adcdb9c68e6fbe4 Mon Sep 17 00:00:00 2001 From: Pino Toscano Date: Mon, 16 Jun 2025 06:41:54 +0200 Subject: [PATCH] run-test262: handle scandir() results with DT_UNKNOWN d_type In case the dirent items returned by scandir() have DT_UNKNOWN as d_type it is not possible to assume they are "non directories", and it is needed to stat() them to get the actual type. Hence, tweak the existing bits to account for that: - create an helper enum for file type to distinguish whether something is for sure a file, whether it is for sure a directory, or it is not known - map d_type to the newly created enum - adapt consider_test_file() to use the newly created enum, and case the file type is not known also to stat() the file to get the actual type On Windows the file type is always known, so there is no need to stat() files. --- run-test262.c | 33 +++++++++++++++++++++++++++++---- 1 file changed, 29 insertions(+), 4 deletions(-) diff --git a/run-test262.c b/run-test262.c index 5dfeb5008..b222a23e7 100644 --- a/run-test262.c +++ b/run-test262.c @@ -31,6 +31,7 @@ #include #include #include +#include #ifdef _WIN32 #include @@ -73,6 +74,12 @@ typedef struct namelist_t { int size; } namelist_t; +enum file_type_t { + file_is_directory, + file_is_not_directory, + file_is_unknown, +}; + long nthreads; // invariant: 0 < nthreads < countof(threads) js_thread_t threads[32]; js_thread_t progress_thread; @@ -407,7 +414,7 @@ static bool ispathsep(int c) return c == '/' || c == '\\'; } -static void consider_test_file(const char *path, const char *name, int is_dir) +static void consider_test_file(const char *path, const char *name, enum file_type_t file_type) { size_t pathlen; char s[1024]; @@ -418,7 +425,13 @@ static void consider_test_file(const char *path, const char *name, int is_dir) while (pathlen > 0 && ispathsep(path[pathlen-1])) pathlen--; snprintf(s, sizeof(s), "%.*s/%s", (int)pathlen, path, name); - if (is_dir) +#ifndef _WIN32 + if (file_type == file_is_unknown) { + struct stat st; + file_type = stat(s, &st) == 0 && S_ISDIR(st.st_mode) ? file_is_directory : file_is_not_directory; + } +#endif + if (file_type == file_is_directory) find_test_files(s); else add_test_file(s); @@ -437,7 +450,7 @@ static void find_test_files(const char *path) do { consider_test_file(path, d.cFileName, - d.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY); + d.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ? file_is_directory : file_is_not_directory); } while (FindNextFileA(h, &d)); FindClose(h); } @@ -448,7 +461,19 @@ static void find_test_files(const char *path) n = scandir(path, &ds, NULL, alphasort); for (i = 0; i < n; i++) { d = ds[i]; - consider_test_file(path, d->d_name, d->d_type == DT_DIR); + enum file_type_t file_type; + switch (d->d_type) { + case DT_DIR: + file_type = file_is_directory; + break; + case DT_UNKNOWN: + file_type = file_is_unknown; + break; + default: + file_type = file_is_not_directory; + break; + } + consider_test_file(path, d->d_name, file_type); free(d); } free(ds);