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