diff --git a/src/coreclr/tools/superpmi/CMakeLists.txt b/src/coreclr/tools/superpmi/CMakeLists.txt index d4308d2e03cabd..c48127c6a70a9d 100644 --- a/src/coreclr/tools/superpmi/CMakeLists.txt +++ b/src/coreclr/tools/superpmi/CMakeLists.txt @@ -1,3 +1,6 @@ +include(configure.cmake) +include_directories(${CMAKE_CURRENT_BINARY_DIR}) + add_subdirectory(superpmi) add_subdirectory(mcs) add_subdirectory(superpmi-shim-collector) diff --git a/src/coreclr/tools/superpmi/config.h.in b/src/coreclr/tools/superpmi/config.h.in new file mode 100644 index 00000000000000..0a065fc23c2a2d --- /dev/null +++ b/src/coreclr/tools/superpmi/config.h.in @@ -0,0 +1,9 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +#ifndef __CONFIG_H__ +#define __CONFIG_H__ + +#cmakedefine01 HAVE_DIRENT_D_TYPE + +#endif // __CONFIG_H__ diff --git a/src/coreclr/tools/superpmi/configure.cmake b/src/coreclr/tools/superpmi/configure.cmake new file mode 100644 index 00000000000000..1b090f956443e3 --- /dev/null +++ b/src/coreclr/tools/superpmi/configure.cmake @@ -0,0 +1,7 @@ +include(CheckStructHasMember) + +check_struct_has_member ("struct dirent" d_type dirent.h HAVE_DIRENT_D_TYPE) + +configure_file( + ${CMAKE_CURRENT_SOURCE_DIR}/config.h.in + ${CMAKE_CURRENT_BINARY_DIR}/config.h) diff --git a/src/coreclr/tools/superpmi/mcs/verbmerge.cpp b/src/coreclr/tools/superpmi/mcs/verbmerge.cpp index e85997864188d1..ccede2d090d7ab 100644 --- a/src/coreclr/tools/superpmi/mcs/verbmerge.cpp +++ b/src/coreclr/tools/superpmi/mcs/verbmerge.cpp @@ -6,12 +6,19 @@ #include "simpletimer.h" #include "logging.h" #include "spmiutil.h" +#include "config.h" #include #ifdef TARGET_UNIX #include #include #include -#endif +#ifndef DT_UNKNOWN +#define DT_UNKNOWN 0 +#define DT_DIR 4 +#define DT_REG 8 +#define DT_LNK 10 +#endif // !DT_UNKNOWN +#endif // TARGET_UNIX #include @@ -187,9 +194,9 @@ bool verbMerge::DirectoryFilterDirectories(FilterArgType* findData) #else // TARGET_WINDOWS if (findData->d_type == DT_DIR) { - if (strcmp(findData->d_name, ".") == 0) + if (u16_strcmp(findData->cFileName, W(".")) == 0) return false; - if (strcmp(findData->d_name, "..") == 0) + if (u16_strcmp(findData->cFileName, W("..")) == 0) return false; return true; @@ -281,12 +288,47 @@ int verbMerge::FilterDirectory(LPCWSTR dir, dirent *pEntry = readdir(pDir); while (pEntry != nullptr) { - if ((fnmatch(searchPatternUtf8.c_str(), pEntry->d_name, 0) == 0) && filter(pEntry)) + int dirEntryType; + +#if HAVE_DIRENT_D_TYPE + dirEntryType = pEntry->d_type; +#else + struct stat sb; + + if (fstatat(dirfd(pDir), pEntry->d_name, &sb, 0) == -1) + { + continue; + } + + if (S_ISDIR(sb.st_mode)) { + dirEntryType = DT_DIR; + } else if (S_ISREG(sb.st_mode)) { + dirEntryType = DT_REG; + } else if (S_ISLNK(sb.st_mode)) { + dirEntryType = DT_LNK; + } else { + dirEntryType = DT_UNKNOWN; + } +#endif + if (dirEntryType == DT_UNKNOWN) { - FindData findData(pEntry->d_type, ConvertMultiByteToWideChar(pEntry->d_name)); - first = new findDataList(&findData, first); - ++elemCount; + continue; } + + if (fnmatch(searchPatternUtf8.c_str(), pEntry->d_name, 0) != 0) + { + continue; + } + + FindData findData(dirEntryType, ConvertMultiByteToWideChar(pEntry->d_name)); + if (!filter(&findData)) + { + continue; + } + + first = new findDataList(&findData, first); + ++elemCount; + errno = 0; pEntry = readdir(pDir); } diff --git a/src/coreclr/tools/superpmi/mcs/verbmerge.h b/src/coreclr/tools/superpmi/mcs/verbmerge.h index 16a326bd372916..ce1eee96b7c522 100644 --- a/src/coreclr/tools/superpmi/mcs/verbmerge.h +++ b/src/coreclr/tools/superpmi/mcs/verbmerge.h @@ -65,7 +65,7 @@ class verbMerge #ifdef TARGET_WINDOWS typedef _WIN32_FIND_DATAW FilterArgType; #else - typedef struct dirent FilterArgType; + typedef struct FindData FilterArgType; #endif typedef bool (*DirectoryFilterFunction_t)(FilterArgType*);