fix compilation
[libjh.git] / fs.c
1 // Copyright (2013) Jann Horn <jann@thejh.net>
2
3 HEADER #include <stdio.h>
4 HEADER #include <sys/types.h>
5 HEADER #include <dirent.h>
6 #include <sys/stat.h>
7
8 #include <errno.h>
9
10 // nonzero iterator exit code means cancel
11 HEADER typedef int dir_iterator(struct dirent *dent, void *data);
12 PUBLIC_FN int fdir_foreach(DIR *d, dir_iterator *iter, void *data) {
13   struct dirent de;
14   struct dirent *res;
15   while (1) {
16     int rd_res = readdir_r(d, &de, &res);
17     if (rd_res) return rd_res;
18     if (res == NULL) return 0;
19     int iter_res = iter(&de, data);
20     if (iter_res) return iter_res;
21   }
22 }
23
24 PUBLIC_FN int dir_foreach(char *path, dir_iterator *iter, void *data) {
25   DIR *d = opendir(path);
26   if (d == NULL) return 1;
27   int feach_res = fdir_foreach(d, iter, data);
28   int errno_ = errno;
29   closedir(d);
30   errno = errno_;
31   return feach_res;
32 }
33
34 PUBLIC_FN int mkdir_maybe(const char *path, mode_t mode) {
35   int r = mkdir(path, mode);
36   if (r && errno != EEXIST) {
37     return r;
38   }
39   return 0;
40 }
41
42 HEADER // requires stdio.h
43 HEADER #define FDIR_FOREACH(dir, element_name, code) {                                                     \
44 HEADER   struct dirent element_name;                                                                       \
45 HEADER   struct dirent *__jh_fdir_foreach_res;                                                             \
46 HEADER   while (1) {                                                                                       \
47 HEADER     int __jh_fdir_foreach_rd_res = readdir_r(dir, &element_name, &__jh_fdir_foreach_res);           \
48 HEADER     if(__jh_fdir_foreach_rd_res) {*(char*)0 = 0; /*crash, boom – EBADF happened (probably)*/}       \
49 HEADER     if (__jh_fdir_foreach_res == NULL) goto end;                                                    \
50 HEADER     {code}                                                                                          \
51 HEADER   }                                                                                                 \
52 HEADER   end:;                                                                                             \
53 HEADER }