3838#include <unistd.h>
3939#include <dirent.h>
4040#include <sys/types.h>
41- #include <pwd.h>
41+
42+ #if !TARGET_OS_WASI
43+ # include <pwd.h>
44+ #endif
45+
4246#include <fcntl.h>
4347
4448#define statinfo stat
@@ -341,7 +345,7 @@ CF_PRIVATE CFMutableArrayRef _CFCreateContentsOfDirectory(CFAllocatorRef alloc,
341345 FindClose (handle );
342346 pathBuf [pathLength ] = '\0' ;
343347
344- #elif TARGET_OS_MAC || TARGET_OS_LINUX || TARGET_OS_BSD
348+ #elif TARGET_OS_MAC || TARGET_OS_LINUX || TARGET_OS_BSD || TARGET_OS_WASI
345349 uint8_t extBuff [CFMaxPathSize ];
346350 int extBuffInteriorDotCount = 0 ; //people insist on using extensions like ".trace.plist", so we need to know how many dots back to look :(
347351
@@ -444,7 +448,7 @@ CF_PRIVATE CFMutableArrayRef _CFCreateContentsOfDirectory(CFAllocatorRef alloc,
444448 dirURL = CFURLCreateFromFileSystemRepresentation (alloc , (uint8_t * )dirPath , pathLength , true);
445449 releaseBase = true;
446450 }
447- #if !defined(__OpenBSD__ )
451+ #if !defined(__OpenBSD__ ) && ! TARGET_OS_WASI
448452 if (dp -> d_type == DT_DIR || dp -> d_type == DT_UNKNOWN || dp -> d_type == DT_LNK || dp -> d_type == DT_WHT ) {
449453#else
450454 if (dp -> d_type == DT_DIR || dp -> d_type == DT_UNKNOWN || dp -> d_type == DT_LNK ) {
@@ -461,13 +465,13 @@ CF_PRIVATE CFMutableArrayRef _CFCreateContentsOfDirectory(CFAllocatorRef alloc,
461465 isDir = ((statBuf .st_mode & S_IFMT ) == S_IFDIR );
462466 }
463467 }
464- #if TARGET_OS_LINUX
468+ #if TARGET_OS_LINUX || TARGET_OS_WASI
465469 fileURL = CFURLCreateFromFileSystemRepresentationRelativeToBase (alloc , (uint8_t * )dp -> d_name , namelen , isDir , dirURL );
466470#else
467471 fileURL = CFURLCreateFromFileSystemRepresentationRelativeToBase (alloc , (uint8_t * )dp -> d_name , dp -> d_namlen , isDir , dirURL );
468472#endif
469473 } else {
470- #if TARGET_OS_LINUX
474+ #if TARGET_OS_LINUX || TARGET_OS_WASI
471475 fileURL = CFURLCreateFromFileSystemRepresentationRelativeToBase (alloc , (uint8_t * )dp -> d_name , namelen , false, dirURL );
472476#else
473477 fileURL = CFURLCreateFromFileSystemRepresentationRelativeToBase (alloc , (uint8_t * )dp -> d_name , dp -> d_namlen , false, dirURL );
@@ -554,7 +558,7 @@ CF_PRIVATE SInt32 _CFGetPathProperties(CFAllocatorRef alloc, char *path, Boolean
554558
555559 if (modTime != NULL ) {
556560 if (fileExists ) {
557- #if TARGET_OS_WIN32 || TARGET_OS_LINUX
561+ #if TARGET_OS_WIN32 || TARGET_OS_LINUX || TARGET_OS_WASI
558562 struct timespec ts = {statBuf .st_mtime , 0 };
559563#else
560564 struct timespec ts = statBuf .st_mtimespec ;
@@ -1118,6 +1122,8 @@ CF_PRIVATE void _CFIterateDirectory(CFStringRef directoryPath, Boolean appendSla
11181122 }
11191123 }
11201124 }
1125+ #elif TARGET_OS_WASI
1126+ CFIndex nameLen = strlen (dent -> d_name );
11211127#else
11221128 CFIndex nameLen = dent -> d_namlen ;
11231129#endif
@@ -1130,7 +1136,25 @@ CF_PRIVATE void _CFIterateDirectory(CFStringRef directoryPath, Boolean appendSla
11301136
11311137 // This buffer has to be 1 bigger than the size of the one in the dirent so we can hold the extra '/' if it's required
11321138 // Be sure to initialize the first character to null, so that strlcat below works correctly
1133- char fullPathToFile [sizeof (dent -> d_name ) + 1 ];
1139+ #if TARGET_OS_WASI
1140+ // wasi-libc's dirent.d_name is not a fixed-size array but a pointer, so we need to calculate
1141+ // the size of buffer at first.
1142+ size_t d_name_size = nameLen ;
1143+ if (stuffToPrefix ) {
1144+ for (CFIndex i = 0 ; i < CFArrayGetCount (stuffToPrefix ); i ++ ) {
1145+ CFStringRef onePrefix = CFArrayGetValueAtIndex (stuffToPrefix , i );
1146+ size_t prefixLen = CFStringGetLength (onePrefix );
1147+ // Add 1 for concatenating '/'
1148+ if (d_name_size > nameLen ) {
1149+ d_name_size += 1 ;
1150+ }
1151+ d_name_size += prefixLen ;
1152+ }
1153+ }
1154+ #else
1155+ size_t d_name_size = sizeof (dent -> d_name );
1156+ #endif
1157+ char fullPathToFile [d_name_size + 1 ];
11341158 fullPathToFile [0 ] = 0 ;
11351159 CFIndex startAt = 0 ;
11361160
0 commit comments