40#  define _POSIX_C_SOURCE  199506L 
   50#if defined(HAVE_PTHREAD) && defined(HAVE_PTHREAD_H) 
   57#define ENTRIES_MIN  (size_t) 32 
   62static pthread_mutex_t scandir_mutex = PTHREAD_MUTEX_INITIALIZER;
 
   81readentry(DIR *dirp, 
struct dirent **entryp, 
size_t *len)
 
   87  if (!pthread_mutex_lock(&scandir_mutex))
 
  106      *len = offsetof(
struct dirent, d_name) + strlen(e->d_name) + (size_t) 1;
 
  107      *entryp = (
struct dirent *) malloc(*len);
 
  110        memcpy((
void *) *entryp, (
void *) e, *len);
 
  112        ((
char *) *entryp)[*len - (size_t) 1] = 0;
 
  122    pthread_mutex_unlock(&scandir_mutex);
 
  132fl_scandir(
const char *dir, 
struct dirent ***namelist,
 
  133           int (*sel)(
struct dirent *),
 
  134           int (*compar)(
struct dirent **, 
struct dirent **))
 
  138  size_t len, num = 0, max = ENTRIES_MIN;
 
  139  struct dirent *entryp, **entries, **p;
 
  141  entries = (
struct dirent **) malloc(
sizeof(*entries) * max);
 
  149      while (!readentry(dirp, &entryp, &len))
 
  158        if (NULL != sel)  { 
if (!sel(entryp))  
continue; }
 
  159        entries[num++] = entryp;
 
  163          if (INT_MAX / 2 >= (
int) max)  { max *= (size_t) 2; }
 
  169          p = (
struct dirent **) realloc((
void *) entries,
 
  170                                         sizeof(*entries) * max);
 
  171          if (NULL != p)  { entries = p; }
 
  186      qsort((
void *) entries, num, 
sizeof(*entries),
 
  187            (
int (*)(
const void *, 
const void *)) compar);
 
  196    while (num--)  { free(entries[num]); }