Git fork
at reftables-rust 114 lines 3.7 kB view raw
1#ifndef DIR_ITERATOR_H 2#define DIR_ITERATOR_H 3 4#include "strbuf.h" 5 6/* 7 * Iterate over a directory tree. 8 * 9 * Iterate over a directory tree, recursively, including paths of all 10 * types and hidden paths. Skip "." and ".." entries and don't follow 11 * symlinks except for the original path. Note that the original path 12 * is not included in the iteration. 13 * 14 * Every time dir_iterator_advance() is called, update the members of 15 * the dir_iterator structure to reflect the next path in the 16 * iteration. The order that paths are iterated over within a 17 * directory is undefined, directory paths are always given before 18 * their contents. 19 * 20 * A typical iteration looks like this: 21 * 22 * int ok; 23 * unsigned int flags = DIR_ITERATOR_PEDANTIC; 24 * struct dir_iterator *iter = dir_iterator_begin(path, flags); 25 * 26 * if (!iter) 27 * goto error_handler; 28 * 29 * while ((ok = dir_iterator_advance(iter)) == ITER_OK) { 30 * if (want_to_stop_iteration()) { 31 * ok = ITER_DONE; 32 * break; 33 * } 34 * 35 * // Access information about the current path: 36 * if (S_ISDIR(iter->st.st_mode)) 37 * printf("%s is a directory\n", iter->relative_path); 38 * } 39 * 40 * if (ok != ITER_DONE) 41 * handle_error(); 42 * dir_iterator_free(iter); 43 * 44 * Callers are allowed to modify iter->path while they are working, 45 * but they must restore it to its original contents before calling 46 * dir_iterator_advance() again. 47 */ 48 49/* 50 * Flags for dir_iterator_begin: 51 * 52 * - DIR_ITERATOR_PEDANTIC: override dir-iterator's default behavior 53 * in case of an error at dir_iterator_advance(), which is to keep 54 * looking for a next valid entry. With this flag, resources are freed 55 * and ITER_ERROR is returned immediately. In both cases, a meaningful 56 * warning is emitted. Note: ENOENT errors are always ignored so that 57 * the API users may remove files during iteration. 58 * 59 * - DIR_ITERATOR_SORTED: sort directory entries alphabetically. 60 */ 61#define DIR_ITERATOR_PEDANTIC (1 << 0) 62#define DIR_ITERATOR_SORTED (1 << 1) 63 64struct dir_iterator { 65 /* The current path: */ 66 struct strbuf path; 67 68 /* 69 * The current path relative to the starting path. This part 70 * of the path always uses "/" characters to separate path 71 * components: 72 */ 73 const char *relative_path; 74 75 /* The current basename: */ 76 const char *basename; 77 78 /* 79 * The result of calling lstat() on path. 80 */ 81 struct stat st; 82}; 83 84/* 85 * Start a directory iteration over path with the combination of 86 * options specified by flags. On success, return a dir_iterator 87 * that holds the internal state of the iteration. In case of 88 * failure, return NULL and set errno accordingly. 89 * 90 * The iteration includes all paths under path, not including path 91 * itself and not including "." or ".." entries. 92 * 93 * Parameters are: 94 * - path is the starting directory. An internal copy will be made. 95 * - flags is a combination of the possible flags to initialize a 96 * dir-iterator or 0 for default behavior. 97 */ 98struct dir_iterator *dir_iterator_begin(const char *path, unsigned int flags); 99 100/* 101 * Advance the iterator to the first or next item and return ITER_OK. 102 * If the iteration is exhausted, free the dir_iterator and any 103 * resources associated with it and return ITER_DONE. 104 * 105 * It is a bug to use iterator or call this function again after it 106 * has returned ITER_DONE or ITER_ERROR (which may be returned iff 107 * the DIR_ITERATOR_PEDANTIC flag was set). 108 */ 109int dir_iterator_advance(struct dir_iterator *iterator); 110 111/* Free the dir_iterator and any associated resources. */ 112void dir_iterator_free(struct dir_iterator *iterator); 113 114#endif