libclod
C library for interacting with NBTs, region files, LOD data and other things.
Loading...
Searching...
No Matches
dir_iter.c
1#include "../platform.h"
2#include "../../error.h"
3#include <dirent.h>
4#include <errno.h>
5#include <string.h>
6#include <fcntl.h>
7#include <unistd.h>
8#include <sys/stat.h>
9
10enum clod_region_result dir_iter_open(dir_iter *iter, const dir d) {
11 auto fd = (int)(intptr_t)d;
12 fd = fcntl(fd, F_DUPFD, 0);
13 if (fd < 0) {
14 return region_error(CLOD_REGION_INVALID_USAGE, "Opening directory iterator: %s", strerror(errno));
15 }
16 DIR *dirp = fdopendir(fd);
17 if (!dirp) {
18 region_error(CLOD_REGION_INVALID_USAGE, "Iterating over directory: %s", strerror(errno));
19 close(fd);
21 }
22 *iter = (uintptr_t)dirp;
23 return CLOD_REGION_OK;
24}
25enum clod_region_result dir_iter_close(const dir_iter iter) {
26 auto const dirp = (DIR *)iter;
27 if (closedir(dirp)) {
28 return region_error(CLOD_REGION_INVALID_USAGE, "Closing directory iterator: %s", strerror(errno));
29 }
30 return CLOD_REGION_OK;
31}
32enum clod_region_result dir_iter_next(const dir_iter iter, const char **name) {
33 auto const dirp = (DIR *)iter;
34
35next_entry:
36 errno = 0;
37 struct dirent *ent = readdir(dirp);
38 if (!ent) {
39 if (errno == 0) {
40 *name = nullptr;
41 return CLOD_REGION_OK;
42 }
43 return region_error(CLOD_REGION_INVALID_USAGE, "Reading directory entry: %s", strerror(errno));
44 }
45
46#ifdef _DIRENT_HAVE_D_TYPE
47 if (ent->d_type != DT_UNKNOWN) {
48 if (ent->d_type != DT_REG) goto next_entry;
49 *name = ent->d_name;
50 return CLOD_REGION_OK;
51 }
52#endif
53 const int fd = dirfd(dirp);
54 if (fd < 0) {
55 return region_error(CLOD_REGION_INVALID_USAGE, "Failed to get dirfd");
56 }
57 struct stat st;
58 if (fstatat(fd, ent->d_name, &st, 0) != 0) {
59 return region_error(CLOD_REGION_INVALID_USAGE, "Failed to stat file %s: %s", ent->d_name, strerror(errno));
60 }
61 if (!S_ISREG(st.st_mode)) goto next_entry;
62
63 *name = ent->d_name;
64 return CLOD_REGION_OK;
65}
clod_region_result
Definition region.h:33
@ CLOD_REGION_INVALID_USAGE
Definition region.h:39
@ CLOD_REGION_OK
Definition region.h:35
Sized string helpers.