@@ -363,14 +363,14 @@ static void ConvertDirent(const struct dirent* entry, struct DirectoryEntry* out
363
363
#endif
364
364
}
365
365
366
- #if HAVE_READDIR_R
366
+ #if IL2CPP_HAVE_READDIR_R_DEPRECATED_DO_NOT_USE
367
367
// struct dirent typically contains 64-bit numbers (e.g. d_ino), so we align it at 8-byte.
368
368
static const size_t dirent_alignment = 8 ;
369
369
#endif
370
370
371
371
int32_t SystemNative_GetReadDirRBufferSize (void )
372
372
{
373
- #if HAVE_READDIR_R
373
+ #if IL2CPP_HAVE_READDIR_R_DEPRECATED_DO_NOT_USE
374
374
// dirent should be under 2k in size
375
375
assert (sizeof (struct dirent ) < 2048 );
376
376
// add some extra space so we can align the buffer to dirent.
@@ -380,17 +380,25 @@ int32_t SystemNative_GetReadDirRBufferSize(void)
380
380
#endif
381
381
}
382
382
383
+ #if READDIR_SORT
384
+ static int cmpstring (const void * p1 , const void * p2 )
385
+ {
386
+ return strcmp (((struct dirent * ) p1 )-> d_name , ((struct dirent * ) p2 )-> d_name );
387
+ }
388
+ #endif
389
+
383
390
// To reduce the number of string copies, the caller of this function is responsible to ensure the memory
384
391
// referenced by outputEntry remains valid until it is read.
385
392
// If the platform supports readdir_r, the caller provides a buffer into which the data is read.
386
393
// If the platform uses readdir, the caller must ensure no calls are made to readdir/closedir since those will invalidate
387
394
// the current dirent. We assume the platform supports concurrent readdir calls to different DIRs.
388
- int32_t SystemNative_ReadDirR (DIR * dir , uint8_t * buffer , int32_t bufferSize , struct DirectoryEntry * outputEntry )
395
+ int32_t SystemNative_ReadDirR (struct DIRWrapper * dirWrapper , uint8_t * buffer , int32_t bufferSize , struct DirectoryEntry * outputEntry )
389
396
{
390
- assert (dir != NULL );
397
+ assert (dirWrapper != NULL );
398
+ assert (dirWrapper -> dir != NULL );
391
399
assert (outputEntry != NULL );
392
400
393
- #if HAVE_READDIR_R
401
+ #if IL2CPP_HAVE_READDIR_R_DEPRECATED_DO_NOT_USE
394
402
assert (buffer != NULL );
395
403
396
404
// align to dirent
@@ -445,7 +453,48 @@ int32_t SystemNative_ReadDirR(DIR* dir, uint8_t* buffer, int32_t bufferSize, str
445
453
(void )buffer ; // unused
446
454
(void )bufferSize ; // unused
447
455
errno = 0 ;
448
- struct dirent * entry = readdir (dir );
456
+
457
+ #if READDIR_SORT
458
+ struct dirent * entry ;
459
+
460
+ if (!dirWrapper -> result )
461
+ {
462
+ size_t numEntries = 0 ;
463
+ while ((entry = readdir (dirWrapper -> dir ))) numEntries ++ ;
464
+ if (numEntries )
465
+ {
466
+ dirWrapper -> result = malloc (numEntries * sizeof (struct dirent ));
467
+ dirWrapper -> curIndex = 0 ;
468
+ dirWrapper -> numEntries = numEntries ;
469
+ #if HAVE_REWINDDIR
470
+ rewinddir (dirWrapper -> dir );
471
+ #else
472
+ closedir (dirWrapper -> dir );
473
+ dirWrapper -> dir = opendir (dirWrapper -> dirPath );
474
+ #endif
475
+ size_t index = 0 ;
476
+ while ((entry = readdir (dirWrapper -> dir )))
477
+ {
478
+ memcpy (& ((struct dirent * )dirWrapper -> result )[index ], entry , sizeof (struct dirent ));
479
+ index ++ ;
480
+ }
481
+
482
+ qsort (dirWrapper -> result , numEntries , sizeof (struct dirent ), cmpstring );
483
+ }
484
+ }
485
+
486
+ if (dirWrapper -> curIndex < dirWrapper -> numEntries )
487
+ {
488
+ entry = & ((struct dirent * )dirWrapper -> result )[dirWrapper -> curIndex ];
489
+ dirWrapper -> curIndex ++ ;
490
+ }
491
+
492
+ else
493
+ entry = NULL ;
494
+
495
+ #else
496
+ struct dirent * entry = readdir (dirWrapper -> dir );
497
+ #endif
449
498
450
499
// 0 returned with null result -> end-of-stream
451
500
if (entry == NULL )
@@ -465,14 +514,41 @@ int32_t SystemNative_ReadDirR(DIR* dir, uint8_t* buffer, int32_t bufferSize, str
465
514
return 0 ;
466
515
}
467
516
468
- DIR * SystemNative_OpenDir (const char * path )
517
+ struct DIRWrapper * SystemNative_OpenDir (const char * path )
469
518
{
470
- return opendir (path );
519
+ DIR * dir = opendir (path );
520
+
521
+ if (dir == NULL )
522
+ return NULL ;
523
+
524
+ struct DIRWrapper * ret = (struct DIRWrapper * )malloc (sizeof (struct DIRWrapper ));
525
+ ret -> dir = dir ;
526
+ #if READDIR_SORT
527
+ ret -> result = NULL ;
528
+ ret -> curIndex = 0 ;
529
+ ret -> numEntries = 0 ;
530
+ #if !HAVE_REWINDDIR
531
+ ret -> dirPath = strdup (path );
532
+ #endif
533
+ #endif
534
+ return ret ;
471
535
}
472
536
473
- int32_t SystemNative_CloseDir (DIR * dir )
537
+ int32_t SystemNative_CloseDir (struct DIRWrapper * dirWrapper )
474
538
{
475
- return closedir (dir );
539
+ assert (dirWrapper != NULL );
540
+ int32_t ret = closedir (dirWrapper -> dir );
541
+ #if READDIR_SORT
542
+ if (dirWrapper -> result )
543
+ free (dirWrapper -> result );
544
+ dirWrapper -> result = NULL ;
545
+ #if !HAVE_REWINDDIR
546
+ if (dirWrapper -> dirPath )
547
+ free (dirWrapper -> dirPath );
548
+ #endif
549
+ free (dirWrapper );
550
+ #endif
551
+ return ret ;
476
552
}
477
553
478
554
int32_t SystemNative_Pipe (int32_t pipeFds [2 ], int32_t flags )
0 commit comments