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