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