Changeset View
Changeset View
Standalone View
Standalone View
lib/libc/gen/scandir.c
Show First 20 Lines • Show All 51 Lines • ▼ Show 20 Lines | |||||
#ifndef __BLOCKS__ | #ifndef __BLOCKS__ | ||||
void | void | ||||
qsort_b(void *, size_t, size_t, void*); | qsort_b(void *, size_t, size_t, void*); | ||||
#endif | #endif | ||||
#else | #else | ||||
#define SELECT(x) select(x) | #define SELECT(x) select(x) | ||||
#endif | #endif | ||||
static int alphasort_thunk(void *thunk, const void *p1, const void *p2); | static int alphasort_thunk(const void *p1, const void *p2, void *thunk); | ||||
int | int | ||||
#ifdef I_AM_SCANDIR_B | #ifdef I_AM_SCANDIR_B | ||||
scandir_b(const char *dirname, struct dirent ***namelist, | scandir_b(const char *dirname, struct dirent ***namelist, | ||||
DECLARE_BLOCK(int, select, const struct dirent *), | DECLARE_BLOCK(int, select, const struct dirent *), | ||||
DECLARE_BLOCK(int, dcomp, const struct dirent **, const struct dirent **)) | DECLARE_BLOCK(int, dcomp, const struct dirent **, const struct dirent **)) | ||||
#else | #else | ||||
scandir(const char *dirname, struct dirent ***namelist, | scandir(const char *dirname, struct dirent ***namelist, | ||||
▲ Show 20 Lines • Show All 47 Lines • ▼ Show 20 Lines | while ((d = readdir(dirp)) != NULL) { | ||||
names[numitems++] = p; | names[numitems++] = p; | ||||
} | } | ||||
closedir(dirp); | closedir(dirp); | ||||
if (numitems && dcomp != NULL) | if (numitems && dcomp != NULL) | ||||
#ifdef I_AM_SCANDIR_B | #ifdef I_AM_SCANDIR_B | ||||
qsort_b(names, numitems, sizeof(struct dirent *), (void*)dcomp); | qsort_b(names, numitems, sizeof(struct dirent *), (void*)dcomp); | ||||
#else | #else | ||||
qsort_r(names, numitems, sizeof(struct dirent *), | qsort_r(names, numitems, sizeof(struct dirent *), | ||||
&dcomp, alphasort_thunk); | alphasort_thunk, &dcomp); | ||||
#endif | #endif | ||||
*namelist = names; | *namelist = names; | ||||
return (numitems); | return (numitems); | ||||
fail: | fail: | ||||
while (numitems > 0) | while (numitems > 0) | ||||
free(names[--numitems]); | free(names[--numitems]); | ||||
free(names); | free(names); | ||||
closedir(dirp); | closedir(dirp); | ||||
return (-1); | return (-1); | ||||
} | } | ||||
/* | /* | ||||
* Alphabetic order comparison routine for those who want it. | * Alphabetic order comparison routine for those who want it. | ||||
* POSIX 2008 requires that alphasort() uses strcoll(). | * POSIX 2008 requires that alphasort() uses strcoll(). | ||||
*/ | */ | ||||
int | int | ||||
alphasort(const struct dirent **d1, const struct dirent **d2) | alphasort(const struct dirent **d1, const struct dirent **d2) | ||||
{ | { | ||||
return (strcoll((*d1)->d_name, (*d2)->d_name)); | return (strcoll((*d1)->d_name, (*d2)->d_name)); | ||||
} | } | ||||
static int | static int | ||||
alphasort_thunk(void *thunk, const void *p1, const void *p2) | alphasort_thunk(const void *p1, const void *p2, void *thunk) | ||||
{ | { | ||||
int (*dc)(const struct dirent **, const struct dirent **); | int (*dc)(const struct dirent **, const struct dirent **); | ||||
dc = *(int (**)(const struct dirent **, const struct dirent **))thunk; | dc = *(int (**)(const struct dirent **, const struct dirent **))thunk; | ||||
return (dc((const struct dirent **)p1, (const struct dirent **)p2)); | return (dc((const struct dirent **)p1, (const struct dirent **)p2)); | ||||
} | } |