summaryrefslogtreecommitdiffstats
path: root/lib/libc/gen/scandir.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libc/gen/scandir.c')
-rw-r--r--lib/libc/gen/scandir.c21
1 files changed, 19 insertions, 2 deletions
diff --git a/lib/libc/gen/scandir.c b/lib/libc/gen/scandir.c
index 47fad1d..b6f76ba 100644
--- a/lib/libc/gen/scandir.c
+++ b/lib/libc/gen/scandir.c
@@ -46,6 +46,8 @@ __FBSDID("$FreeBSD$");
#include <string.h>
#include "un-namespace.h"
+static int alphasort_thunk(void *thunk, const void *p1, const void *p2);
+
/*
* The DIRSIZ macro is the minimum record length which will hold the directory
* entry. This requires the amount of space in struct dirent without the
@@ -109,8 +111,8 @@ scandir(const char *dirname, struct dirent ***namelist,
}
closedir(dirp);
if (nitems && dcomp != NULL)
- qsort(names, nitems, sizeof(struct dirent *),
- (int (*)(const void *, const void *))dcomp);
+ qsort_r(names, nitems, sizeof(struct dirent *),
+ &dcomp, alphasort_thunk);
*namelist = names;
return (nitems);
@@ -124,6 +126,12 @@ fail:
/*
* Alphabetic order comparison routine for those who want it.
+ *
+ * XXXKIB POSIX 2008 requires the alphasort() to use strcoll(). Keep
+ * strcmp() for now, since environment locale settings could have no
+ * relevance for the byte sequence of the file name. Moreover, it
+ * might be even invalid sequence in current locale, and then
+ * behaviour of alphasort would be undefined.
*/
int
alphasort(const struct dirent **d1, const struct dirent **d2)
@@ -131,3 +139,12 @@ alphasort(const struct dirent **d1, const struct dirent **d2)
return (strcmp((*d1)->d_name, (*d2)->d_name));
}
+
+static int
+alphasort_thunk(void *thunk, const void *p1, const void *p2)
+{
+ int (*dc)(const struct dirent **, const struct dirent **);
+
+ dc = *(int (**)(const struct dirent **, const struct dirent **))thunk;
+ return (dc((const struct dirent **)p1, (const struct dirent **)p2));
+}
OpenPOWER on IntegriCloud