1*c9945492SAndroid Build Coastguard Worker #include <dirent.h>
2*c9945492SAndroid Build Coastguard Worker #include <string.h>
3*c9945492SAndroid Build Coastguard Worker #include <stdlib.h>
4*c9945492SAndroid Build Coastguard Worker #include <stdint.h>
5*c9945492SAndroid Build Coastguard Worker #include <errno.h>
6*c9945492SAndroid Build Coastguard Worker #include <stddef.h>
7*c9945492SAndroid Build Coastguard Worker
scandir(const char * path,struct dirent *** res,int (* sel)(const struct dirent *),int (* cmp)(const struct dirent **,const struct dirent **))8*c9945492SAndroid Build Coastguard Worker int scandir(const char *path, struct dirent ***res,
9*c9945492SAndroid Build Coastguard Worker int (*sel)(const struct dirent *),
10*c9945492SAndroid Build Coastguard Worker int (*cmp)(const struct dirent **, const struct dirent **))
11*c9945492SAndroid Build Coastguard Worker {
12*c9945492SAndroid Build Coastguard Worker DIR *d = opendir(path);
13*c9945492SAndroid Build Coastguard Worker struct dirent *de, **names=0, **tmp;
14*c9945492SAndroid Build Coastguard Worker size_t cnt=0, len=0;
15*c9945492SAndroid Build Coastguard Worker int old_errno = errno;
16*c9945492SAndroid Build Coastguard Worker
17*c9945492SAndroid Build Coastguard Worker if (!d) return -1;
18*c9945492SAndroid Build Coastguard Worker
19*c9945492SAndroid Build Coastguard Worker while ((errno=0), (de = readdir(d))) {
20*c9945492SAndroid Build Coastguard Worker if (sel && !sel(de)) continue;
21*c9945492SAndroid Build Coastguard Worker if (cnt >= len) {
22*c9945492SAndroid Build Coastguard Worker len = 2*len+1;
23*c9945492SAndroid Build Coastguard Worker if (len > SIZE_MAX/sizeof *names) break;
24*c9945492SAndroid Build Coastguard Worker tmp = realloc(names, len * sizeof *names);
25*c9945492SAndroid Build Coastguard Worker if (!tmp) break;
26*c9945492SAndroid Build Coastguard Worker names = tmp;
27*c9945492SAndroid Build Coastguard Worker }
28*c9945492SAndroid Build Coastguard Worker names[cnt] = malloc(de->d_reclen);
29*c9945492SAndroid Build Coastguard Worker if (!names[cnt]) break;
30*c9945492SAndroid Build Coastguard Worker memcpy(names[cnt++], de, de->d_reclen);
31*c9945492SAndroid Build Coastguard Worker }
32*c9945492SAndroid Build Coastguard Worker
33*c9945492SAndroid Build Coastguard Worker closedir(d);
34*c9945492SAndroid Build Coastguard Worker
35*c9945492SAndroid Build Coastguard Worker if (errno) {
36*c9945492SAndroid Build Coastguard Worker if (names) while (cnt-->0) free(names[cnt]);
37*c9945492SAndroid Build Coastguard Worker free(names);
38*c9945492SAndroid Build Coastguard Worker return -1;
39*c9945492SAndroid Build Coastguard Worker }
40*c9945492SAndroid Build Coastguard Worker errno = old_errno;
41*c9945492SAndroid Build Coastguard Worker
42*c9945492SAndroid Build Coastguard Worker if (cmp) qsort(names, cnt, sizeof *names, (int (*)(const void *, const void *))cmp);
43*c9945492SAndroid Build Coastguard Worker *res = names;
44*c9945492SAndroid Build Coastguard Worker return cnt;
45*c9945492SAndroid Build Coastguard Worker }
46