blob: cc1f2ba94e211d85205f83646405250651f6721e [file] [log] [blame]
#include <dirent.h>
#include <errno.h>
#include <stddef.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
int scandir(const char* path, struct dirent*** res, int (*sel)(const struct dirent*),
int (*cmp)(const struct dirent**, const struct dirent**)) {
DIR* d = opendir(path);
struct dirent *de, **names = 0, **tmp;
size_t cnt = 0, len = 0;
int old_errno = errno;
if (!d)
return -1;
while ((errno = 0), (de = readdir(d))) {
if (sel && !sel(de))
continue;
if (cnt >= len) {
len = 2 * len + 1;
if (len > SIZE_MAX / sizeof *names)
break;
tmp = realloc(names, len * sizeof *names);
if (!tmp)
break;
names = tmp;
}
names[cnt] = malloc(de->d_reclen);
if (!names[cnt])
break;
memcpy(names[cnt++], de, de->d_reclen);
}
closedir(d);
if (errno) {
if (names)
while (cnt-- > 0)
free(names[cnt]);
free(names);
return -1;
}
errno = old_errno;
if (cmp)
qsort(names, cnt, sizeof *names, (int (*)(const void*, const void*))cmp);
*res = names;
return cnt;
}