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]); }