Skip to content

Commit fde7c8f

Browse files
authored
Fix illumos compile errors in coreclr/tools/superpmi/mcs/verbmerge.cpp (dotnet#117464)
/runtime/src/coreclr/tools/superpmi/mcs/verbmerge.cpp: In static member function 'static bool verbMerge::DirectoryFilterDirectories(FilterArgType*)': /runtime/src/coreclr/tools/superpmi/mcs/verbmerge.cpp:188:19: error: 'verbMerge::FilterArgType' {aka 'struct dirent'} has no member named 'd_type' 188 | if (findData->d_type == DT_DIR) | ^~~~~~ For the fix, do similarly as: src/native/corehost/hostmisc/pal.unix.cpp Let FilterArgType use struct FindData to simplify filters. Handle the possibility of finding d_type == DT_UNKOWN Add HAVE_DIRENT_D_TYPE introspection
1 parent c523659 commit fde7c8f

File tree

5 files changed

+77
-11
lines changed

5 files changed

+77
-11
lines changed

src/coreclr/tools/superpmi/CMakeLists.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
include(configure.cmake)
2+
include_directories(${CMAKE_CURRENT_BINARY_DIR})
3+
14
add_subdirectory(superpmi)
25
add_subdirectory(mcs)
36
add_subdirectory(superpmi-shim-collector)
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
4+
#ifndef __CONFIG_H__
5+
#define __CONFIG_H__
6+
7+
#cmakedefine01 HAVE_DIRENT_D_TYPE
8+
9+
#endif // __CONFIG_H__
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
include(CheckStructHasMember)
2+
3+
check_struct_has_member ("struct dirent" d_type dirent.h HAVE_DIRENT_D_TYPE)
4+
5+
configure_file(
6+
${CMAKE_CURRENT_SOURCE_DIR}/config.h.in
7+
${CMAKE_CURRENT_BINARY_DIR}/config.h)

src/coreclr/tools/superpmi/mcs/verbmerge.cpp

Lines changed: 57 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,19 @@
66
#include "simpletimer.h"
77
#include "logging.h"
88
#include "spmiutil.h"
9+
#include "config.h"
910
#include <stdio.h>
1011
#ifdef TARGET_UNIX
1112
#include <sys/types.h>
1213
#include <dirent.h>
1314
#include <fnmatch.h>
14-
#endif
15+
#if !HAVE_DIRENT_D_TYPE
16+
#define DT_UNKNOWN 0
17+
#define DT_DIR 4
18+
#define DT_REG 8
19+
#define DT_LNK 10
20+
#endif // !HAVE_DIRENT_D_TYPE
21+
#endif // TARGET_UNIX
1522

1623
#include <utility>
1724

@@ -187,9 +194,9 @@ bool verbMerge::DirectoryFilterDirectories(FilterArgType* findData)
187194
#else // TARGET_WINDOWS
188195
if (findData->d_type == DT_DIR)
189196
{
190-
if (strcmp(findData->d_name, ".") == 0)
197+
if (u16_strcmp(findData->cFileName, W(".")) == 0)
191198
return false;
192-
if (strcmp(findData->d_name, "..") == 0)
199+
if (u16_strcmp(findData->cFileName, W("..")) == 0)
193200
return false;
194201

195202
return true;
@@ -277,18 +284,58 @@ int verbMerge::FilterDirectory(LPCWSTR dir,
277284
DIR* pDir = opendir(dirUtf8.c_str());
278285
if (pDir != nullptr)
279286
{
280-
errno = 0;
281-
dirent *pEntry = readdir(pDir);
282-
while (pEntry != nullptr)
287+
while (true)
283288
{
284-
if ((fnmatch(searchPatternUtf8.c_str(), pEntry->d_name, 0) == 0) && filter(pEntry))
289+
dirent *pEntry;
290+
int dirEntryType;
291+
292+
errno = 0;
293+
pEntry = readdir(pDir);
294+
if (pEntry == nullptr)
295+
break;
296+
297+
#if HAVE_DIRENT_D_TYPE
298+
dirEntryType = pEntry->d_type;
299+
#else
300+
dirEntryType = DT_UNKNOWN;
301+
#endif
302+
// On some systems, dirent contains a d_type field, but note:
303+
// some file systems MAY leave d_type == DT_UNKNOWN,
304+
// expecting the consumer to stat the file. On systems
305+
// without a d_type simply always stat the file.
306+
307+
if (dirEntryType == DT_UNKNOWN)
285308
{
286-
FindData findData(pEntry->d_type, ConvertMultiByteToWideChar(pEntry->d_name));
309+
struct stat sb;
310+
311+
if (fstatat(dirfd(pDir), pEntry->d_name, &sb, 0) == -1)
312+
continue;
313+
314+
if (S_ISDIR(sb.st_mode))
315+
dirEntryType = DT_DIR;
316+
else if (S_ISREG(sb.st_mode))
317+
dirEntryType = DT_REG;
318+
else if (S_ISLNK(sb.st_mode))
319+
dirEntryType = DT_LNK;
320+
else
321+
dirEntryType = DT_UNKNOWN;
322+
323+
}
324+
325+
if (dirEntryType == DT_UNKNOWN)
326+
continue;
327+
328+
if (fnmatch(searchPatternUtf8.c_str(), pEntry->d_name, 0) != 0)
329+
continue;
330+
331+
// Call the filter with &FindData like the Windows code below.
332+
FindData findData(dirEntryType, ConvertMultiByteToWideChar(pEntry->d_name));
333+
if (filter(&findData))
334+
{
335+
// Prepend it to the list.
287336
first = new findDataList(&findData, first);
288337
++elemCount;
289338
}
290-
errno = 0;
291-
pEntry = readdir(pDir);
292339
}
293340

294341
if (errno != 0)

src/coreclr/tools/superpmi/mcs/verbmerge.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ class verbMerge
6565
#ifdef TARGET_WINDOWS
6666
typedef _WIN32_FIND_DATAW FilterArgType;
6767
#else
68-
typedef struct dirent FilterArgType;
68+
typedef struct FindData FilterArgType;
6969
#endif
7070

7171
typedef bool (*DirectoryFilterFunction_t)(FilterArgType*);

0 commit comments

Comments
 (0)