diff options
-rw-r--r-- | bftw.c | 397 |
1 files changed, 198 insertions, 199 deletions
@@ -17,17 +17,16 @@ /** * The bftw() implementation consists of the following components: * - * - struct bftw_dir: A directory that has been encountered during the - * traversal. They have reference-counted links to their parents in the - * directory tree. + * - struct bftw_file: A file that has been encountered during the traversal. + * They have reference-counted links to their parents in the directory tree. * - * - struct bftw_cache: Holds bftw_dir's with open file descriptors, used for + * - struct bftw_cache: Holds bftw_file's with open file descriptors, used for * openat() to minimize the amount of path re-traversals that need to happen. * Currently implemented as a priority queue based on depth and reference * count. * - * - struct bftw_queue: The queue of bftw_dir's left to explore. Implemented as - * a simple circular buffer. + * - struct bftw_queue: The queue of bftw_file's left to explore. Implemented + * as a simple circular buffer. * * - struct bftw_state: Represents the current state of the traversal, allowing * bftw() to be factored into various helper functions. @@ -49,23 +48,23 @@ #include <unistd.h> /** - * A directory. + * A file. */ -struct bftw_dir { +struct bftw_file { /** The parent directory, if any. */ - struct bftw_dir *parent; - /** This directory's depth in the walk. */ + struct bftw_file *parent; + /** This file's depth in the walk. */ size_t depth; - /** The next directory in the queue, if any. */ - struct bftw_dir *next; + /** The next file in the queue, if any. */ + struct bftw_file *next; /** Reference count. */ size_t refcount; /** Index in the bftw_cache priority queue. */ size_t heap_index; - /** An open file descriptor to this directory, or -1. */ + /** An open descriptor to this file, or -1. */ int fd; /** The device number, for cycle detection. */ @@ -73,11 +72,11 @@ struct bftw_dir { /** The inode number, for cycle detection. */ ino_t ino; - /** The offset of this directory in the full path. */ + /** The offset of this file in the full path. */ size_t nameoff; - /** The length of the directory's name. */ + /** The length of the file's name. */ size_t namelen; - /** The directory's name. */ + /** The file's name. */ char name[]; }; @@ -86,7 +85,7 @@ struct bftw_dir { */ struct bftw_cache { /** A min-heap of open directories. */ - struct bftw_dir **heap; + struct bftw_file **heap; /** Current heap size. */ size_t size; /** Maximum heap size. */ @@ -112,7 +111,7 @@ static void bftw_cache_destroy(struct bftw_cache *cache) { } /** Check if two heap entries are in heap order. */ -static bool bftw_heap_check(const struct bftw_dir *parent, const struct bftw_dir *child) { +static bool bftw_heap_check(const struct bftw_file *parent, const struct bftw_file *child) { if (parent->depth > child->depth) { return true; } else if (parent->depth < child->depth) { @@ -122,20 +121,20 @@ static bool bftw_heap_check(const struct bftw_dir *parent, const struct bftw_dir } } -/** Move a bftw_dir to a particular place in the heap. */ -static void bftw_heap_move(struct bftw_cache *cache, struct bftw_dir *dir, size_t i) { - cache->heap[i] = dir; - dir->heap_index = i; +/** Move a bftw_file to a particular place in the heap. */ +static void bftw_heap_move(struct bftw_cache *cache, struct bftw_file *file, size_t i) { + cache->heap[i] = file; + file->heap_index = i; } /** Bubble an entry up the heap. */ -static void bftw_heap_bubble_up(struct bftw_cache *cache, struct bftw_dir *dir) { - size_t i = dir->heap_index; +static void bftw_heap_bubble_up(struct bftw_cache *cache, struct bftw_file *file) { + size_t i = file->heap_index; while (i > 0) { size_t pi = (i - 1)/2; - struct bftw_dir *parent = cache->heap[pi]; - if (bftw_heap_check(parent, dir)) { + struct bftw_file *parent = cache->heap[pi]; + if (bftw_heap_check(parent, file)) { break; } @@ -143,12 +142,12 @@ static void bftw_heap_bubble_up(struct bftw_cache *cache, struct bftw_dir *dir) i = pi; } - bftw_heap_move(cache, dir, i); + bftw_heap_move(cache, file, i); } /** Bubble an entry down the heap. */ -static void bftw_heap_bubble_down(struct bftw_cache *cache, struct bftw_dir *dir) { - size_t i = dir->heap_index; +static void bftw_heap_bubble_down(struct bftw_cache *cache, struct bftw_file *file) { + size_t i = file->heap_index; while (true) { size_t ci = 2*i + 1; @@ -156,18 +155,18 @@ static void bftw_heap_bubble_down(struct bftw_cache *cache, struct bftw_dir *dir break; } - struct bftw_dir *child = cache->heap[ci]; + struct bftw_file *child = cache->heap[ci]; size_t ri = ci + 1; if (ri < cache->size) { - struct bftw_dir *right = cache->heap[ri]; + struct bftw_file *right = cache->heap[ri]; if (!bftw_heap_check(child, right)) { ci = ri; child = right; } } - if (bftw_heap_check(dir, child)) { + if (bftw_heap_check(file, child)) { break; } @@ -175,81 +174,81 @@ static void bftw_heap_bubble_down(struct bftw_cache *cache, struct bftw_dir *dir i = ci; } - bftw_heap_move(cache, dir, i); + bftw_heap_move(cache, file, i); } /** Bubble an entry up or down the heap. */ -static void bftw_heap_bubble(struct bftw_cache *cache, struct bftw_dir *dir) { - size_t i = dir->heap_index; +static void bftw_heap_bubble(struct bftw_cache *cache, struct bftw_file *file) { + size_t i = file->heap_index; if (i > 0) { size_t pi = (i - 1)/2; - struct bftw_dir *parent = cache->heap[pi]; - if (!bftw_heap_check(parent, dir)) { - bftw_heap_bubble_up(cache, dir); + struct bftw_file *parent = cache->heap[pi]; + if (!bftw_heap_check(parent, file)) { + bftw_heap_bubble_up(cache, file); return; } } - bftw_heap_bubble_down(cache, dir); + bftw_heap_bubble_down(cache, file); } -/** Increment a bftw_dir's reference count. */ -static void bftw_dir_incref(struct bftw_cache *cache, struct bftw_dir *dir) { - ++dir->refcount; +/** Increment a bftw_file's reference count. */ +static void bftw_file_incref(struct bftw_cache *cache, struct bftw_file *file) { + ++file->refcount; - if (dir->fd >= 0) { - bftw_heap_bubble_down(cache, dir); + if (file->fd >= 0) { + bftw_heap_bubble_down(cache, file); } } -/** Decrement a bftw_dir's reference count. */ -static void bftw_dir_decref(struct bftw_cache *cache, struct bftw_dir *dir) { - --dir->refcount; +/** Decrement a bftw_file's reference count. */ +static void bftw_file_decref(struct bftw_cache *cache, struct bftw_file *file) { + --file->refcount; - if (dir->fd >= 0) { - bftw_heap_bubble_up(cache, dir); + if (file->fd >= 0) { + bftw_heap_bubble_up(cache, file); } } -/** Add a bftw_dir to the cache. */ -static void bftw_cache_add(struct bftw_cache *cache, struct bftw_dir *dir) { +/** Add a bftw_file to the cache. */ +static void bftw_cache_add(struct bftw_cache *cache, struct bftw_file *file) { assert(cache->size < cache->capacity); - assert(dir->fd >= 0); + assert(file->fd >= 0); size_t size = cache->size++; - dir->heap_index = size; - bftw_heap_bubble_up(cache, dir); + file->heap_index = size; + bftw_heap_bubble_up(cache, file); } -/** Remove a bftw_dir from the cache. */ -static void bftw_cache_remove(struct bftw_cache *cache, struct bftw_dir *dir) { +/** Remove a bftw_file from the cache. */ +static void bftw_cache_remove(struct bftw_cache *cache, struct bftw_file *file) { assert(cache->size > 0); - assert(dir->fd >= 0); + assert(file->fd >= 0); size_t size = --cache->size; - size_t i = dir->heap_index; + size_t i = file->heap_index; if (i != size) { - struct bftw_dir *end = cache->heap[size]; + struct bftw_file *end = cache->heap[size]; end->heap_index = i; bftw_heap_bubble(cache, end); } } -/** Close a bftw_dir. */ -static void bftw_dir_close(struct bftw_cache *cache, struct bftw_dir *dir) { - assert(dir->fd >= 0); +/** Close a bftw_file. */ +static void bftw_file_close(struct bftw_cache *cache, struct bftw_file *file) { + assert(file->fd >= 0); - bftw_cache_remove(cache, dir); + bftw_cache_remove(cache, file); - close(dir->fd); - dir->fd = -1; + close(file->fd); + file->fd = -1; } /** Pop a directory from the cache. */ static void bftw_cache_pop(struct bftw_cache *cache) { assert(cache->size > 0); - bftw_dir_close(cache, cache->heap[0]); + bftw_file_close(cache, cache->heap[0]); } /** @@ -258,23 +257,23 @@ static void bftw_cache_pop(struct bftw_cache *cache) { * @param cache * The cache in question. * @param saved - * A bftw_dir that must be preserved. + * A bftw_file that must be preserved. * @return * 0 if successfully shrunk, otherwise -1. */ -static int bftw_cache_shrink(struct bftw_cache *cache, const struct bftw_dir *saved) { +static int bftw_cache_shrink(struct bftw_cache *cache, const struct bftw_file *saved) { int ret = -1; - struct bftw_dir *dir = NULL; + struct bftw_file *file = NULL; if (cache->size >= 1) { - dir = cache->heap[0]; - if (dir == saved && cache->size >= 2) { - dir = cache->heap[1]; + file = cache->heap[0]; + if (file == saved && cache->size >= 2) { + file = cache->heap[1]; } } - if (dir && dir != saved) { - bftw_dir_close(cache, dir); + if (file && file != saved) { + bftw_file_close(cache, file); ret = 0; } @@ -282,10 +281,10 @@ static int bftw_cache_shrink(struct bftw_cache *cache, const struct bftw_dir *sa return ret; } -/** Create a new bftw_dir. */ -static struct bftw_dir *bftw_dir_new(struct bftw_cache *cache, struct bftw_dir *parent, const char *name) { +/** Create a new bftw_file. */ +static struct bftw_file *bftw_file_new(struct bftw_cache *cache, struct bftw_file *parent, const char *name) { size_t namelen = strlen(name); - size_t size = sizeof(struct bftw_dir) + namelen + 1; + size_t size = sizeof(struct bftw_file) + namelen + 1; bool needs_slash = false; if (namelen == 0 || name[namelen - 1] != '/') { @@ -293,54 +292,54 @@ static struct bftw_dir *bftw_dir_new(struct bftw_cache *cache, struct bftw_dir * ++size; } - struct bftw_dir *dir = malloc(size); - if (!dir) { + struct bftw_file *file = malloc(size); + if (!file) { return NULL; } - dir->parent = parent; + file->parent = parent; if (parent) { - dir->depth = parent->depth + 1; - dir->nameoff = parent->nameoff + parent->namelen; - bftw_dir_incref(cache, parent); + file->depth = parent->depth + 1; + file->nameoff = parent->nameoff + parent->namelen; + bftw_file_incref(cache, parent); } else { - dir->depth = 0; - dir->nameoff = 0; + file->depth = 0; + file->nameoff = 0; } - dir->next = NULL; + file->next = NULL; - dir->refcount = 1; - dir->fd = -1; + file->refcount = 1; + file->fd = -1; - dir->dev = -1; - dir->ino = -1; + file->dev = -1; + file->ino = -1; - memcpy(dir->name, name, namelen); + memcpy(file->name, name, namelen); if (needs_slash) { - dir->name[namelen++] = '/'; + file->name[namelen++] = '/'; } - dir->name[namelen] = '\0'; - dir->namelen = namelen; + file->name[namelen] = '\0'; + file->namelen = namelen; - return dir; + return file; } /** - * Compute the path to a bftw_dir. + * Compute the path to a bftw_file. */ -static int bftw_dir_path(const struct bftw_dir *dir, char **path) { - size_t pathlen = dir->nameoff + dir->namelen; +static int bftw_file_path(const struct bftw_file *file, char **path) { + size_t pathlen = file->nameoff + file->namelen; if (dstresize(path, pathlen) != 0) { return -1; } char *dest = *path; // Build the path backwards - while (dir) { - memcpy(dest + dir->nameoff, dir->name, dir->namelen); - dir = dir->parent; + while (file) { + memcpy(dest + file->nameoff, file->name, file->namelen); + file = file->parent; } return 0; @@ -349,16 +348,16 @@ static int bftw_dir_path(const struct bftw_dir *dir, char **path) { /** * Get the appropriate (fd, path) pair for the *at() family of functions. * - * @param dir - * The directory being accessed. + * @param file + * The file being accessed. * @param[out] at_fd * Will hold the appropriate file descriptor to use. * @param[in,out] at_path * Will hold the appropriate path to use. * @return The closest open ancestor file. */ -static struct bftw_dir *bftw_dir_base(struct bftw_dir *dir, int *at_fd, const char **at_path) { - struct bftw_dir *base = dir; +static struct bftw_file *bftw_file_base(struct bftw_file *file, int *at_fd, const char **at_path) { + struct bftw_file *base = file; do { base = base->parent; @@ -373,23 +372,23 @@ static struct bftw_dir *bftw_dir_base(struct bftw_dir *dir, int *at_fd, const ch } /** - * Open a bftw_dir relative to another one. + * Open a bftw_file relative to another one. * * @param cache - * The cache containing the dir. - * @param dir - * The directory to open. + * The cache containing the file. + * @param file + * The file to open. * @param base * The base directory for the relative path (may be NULL). * @param at_fd * The base file descriptor, AT_FDCWD if base == NULL. * @param at_path - * The relative path to the dir. + * The relative path to the file. * @return * The opened file descriptor, or negative on error. */ -static int bftw_dir_openat(struct bftw_cache *cache, struct bftw_dir *dir, const struct bftw_dir *base, int at_fd, const char *at_path) { - assert(dir->fd < 0); +static int bftw_file_openat(struct bftw_cache *cache, struct bftw_file *file, const struct bftw_file *base, int at_fd, const char *at_path) { + assert(file->fd < 0); int flags = O_RDONLY | O_CLOEXEC | O_DIRECTORY; int fd = openat(at_fd, at_path, flags); @@ -405,31 +404,31 @@ static int bftw_dir_openat(struct bftw_cache *cache, struct bftw_dir *dir, const bftw_cache_pop(cache); } - dir->fd = fd; - bftw_cache_add(cache, dir); + file->fd = fd; + bftw_cache_add(cache, file); } return fd; } /** - * Open a bftw_dir. + * Open a bftw_file. * * @param cache - * The cache containing the directory. - * @param dir - * The directory to open. + * The cache to hold the file. + * @param file + * The file to open. * @param path - * The full path to the dir. + * The full path to the file. * @return * The opened file descriptor, or negative on error. */ -static int bftw_dir_open(struct bftw_cache *cache, struct bftw_dir *dir, const char *path) { +static int bftw_file_open(struct bftw_cache *cache, struct bftw_file *file, const char *path) { int at_fd = AT_FDCWD; const char *at_path = path; - struct bftw_dir *base = bftw_dir_base(dir, &at_fd, &at_path); + struct bftw_file *base = bftw_file_base(file, &at_fd, &at_path); - int fd = bftw_dir_openat(cache, dir, base, at_fd, at_path); + int fd = bftw_file_openat(cache, file, base, at_fd, at_path); if (fd >= 0 || errno != ENAMETOOLONG) { return fd; } @@ -438,24 +437,24 @@ static int bftw_dir_open(struct bftw_cache *cache, struct bftw_dir *dir, const c // -1 to include the root, which has depth == 0 size_t offset = base ? base->depth : -1; - size_t levels = dir->depth - offset; + size_t levels = file->depth - offset; if (levels < 2) { return fd; } - struct bftw_dir **parents = malloc(levels * sizeof(*parents)); + struct bftw_file **parents = malloc(levels * sizeof(*parents)); if (!parents) { return fd; } - struct bftw_dir *parent = dir; + struct bftw_file *parent = file; for (size_t i = levels; i-- > 0;) { parents[i] = parent; parent = parent->parent; } for (size_t i = 0; i < levels; ++i) { - fd = bftw_dir_openat(cache, parents[i], base, at_fd, parents[i]->name); + fd = bftw_file_openat(cache, parents[i], base, at_fd, parents[i]->name); if (fd < 0) { break; } @@ -469,19 +468,19 @@ static int bftw_dir_open(struct bftw_cache *cache, struct bftw_dir *dir, const c } /** - * Open a DIR* for a bftw_dir. + * Open a DIR* for a bftw_file. * * @param cache - * The cache containing the directory. - * @param dir + * The cache to hold the file. + * @param file * The directory to open. * @param path * The full path to the directory. * @return * The opened DIR *, or NULL on error. */ -static DIR *bftw_dir_opendir(struct bftw_cache *cache, struct bftw_dir *dir, const char *path) { - int fd = bftw_dir_open(cache, dir, path); +static DIR *bftw_file_opendir(struct bftw_cache *cache, struct bftw_file *file, const char *path) { + int fd = bftw_file_open(cache, file, path); if (fd < 0) { return NULL; } @@ -494,7 +493,7 @@ static DIR *bftw_dir_opendir(struct bftw_cache *cache, struct bftw_dir *dir, con int dfd = dup_cloexec(fd); if (dfd < 0 && errno == EMFILE) { - if (bftw_cache_shrink(cache, dir) == 0) { + if (bftw_cache_shrink(cache, file) == 0) { dfd = dup_cloexec(fd); } } @@ -513,23 +512,23 @@ static DIR *bftw_dir_opendir(struct bftw_cache *cache, struct bftw_dir *dir, con return ret; } -/** Free a bftw_dir. */ -static void bftw_dir_free(struct bftw_cache *cache, struct bftw_dir *dir) { - assert(dir->refcount == 0); +/** Free a bftw_file. */ +static void bftw_file_free(struct bftw_cache *cache, struct bftw_file *file) { + assert(file->refcount == 0); - if (dir->fd >= 0) { - bftw_dir_close(cache, dir); + if (file->fd >= 0) { + bftw_file_close(cache, file); } - free(dir); + free(file); } /** * A directory reader. */ struct bftw_reader { - /** The directory object. */ - struct bftw_dir *dir; + /** The file object. */ + struct bftw_file *file; /** The path to the directory. */ char *path; /** The open handle to the directory. */ @@ -547,7 +546,7 @@ static int bftw_reader_init(struct bftw_reader *reader) { return -1; } - reader->dir = NULL; + reader->file = NULL; reader->handle = NULL; reader->de = NULL; reader->error = 0; @@ -565,20 +564,20 @@ static int bftw_reader_read(struct bftw_reader *reader) { } /** Open a directory for reading. */ -static int bftw_reader_open(struct bftw_reader *reader, struct bftw_cache *cache, struct bftw_dir *dir) { +static int bftw_reader_open(struct bftw_reader *reader, struct bftw_cache *cache, struct bftw_file *file) { assert(!reader->handle); assert(!reader->de); - reader->dir = dir; + reader->file = file; reader->error = 0; - if (bftw_dir_path(dir, &reader->path) != 0) { + if (bftw_file_path(file, &reader->path) != 0) { reader->error = errno; dstresize(&reader->path, 0); return -1; } - reader->handle = bftw_dir_opendir(cache, dir, reader->path); + reader->handle = bftw_file_opendir(cache, file, reader->path); if (!reader->handle) { reader->error = errno; return -1; @@ -613,13 +612,13 @@ static void bftw_reader_destroy(struct bftw_reader *reader) { } /** - * A queue of bftw_dir's to examine. + * A queue of bftw_file's to examine. */ struct bftw_queue { /** The head of the queue. */ - struct bftw_dir *head; + struct bftw_file *head; /** The tail of the queue. */ - struct bftw_dir *tail; + struct bftw_file *tail; }; /** Initialize a bftw_queue. */ @@ -628,28 +627,28 @@ static void bftw_queue_init(struct bftw_queue *queue) { queue->tail = NULL; } -/** Add a directory to the bftw_queue. */ -static void bftw_queue_push(struct bftw_queue *queue, struct bftw_dir *dir) { - assert(dir->next == NULL); +/** Add a file to the bftw_queue. */ +static void bftw_queue_push(struct bftw_queue *queue, struct bftw_file *file) { + assert(file->next == NULL); if (!queue->head) { - queue->head = dir; + queue->head = file; } if (queue->tail) { - queue->tail->next = dir; + queue->tail->next = file; } - queue->tail = dir; + queue->tail = file; } -/** Pop the next directory from the queue. */ -static struct bftw_dir *bftw_queue_pop(struct bftw_queue *queue) { - struct bftw_dir *dir = queue->head; - queue->head = dir->next; - if (queue->tail == dir) { +/** Pop the next file from the queue. */ +static struct bftw_file *bftw_queue_pop(struct bftw_queue *queue) { + struct bftw_file *file = queue->head; + queue->head = file->next; + if (queue->tail == file) { queue->tail = NULL; } - dir->next = NULL; - return dir; + file->next = NULL; + return file; } enum bftw_typeflag bftw_mode_typeflag(mode_t mode) { @@ -777,7 +776,7 @@ struct bftw_state { /** The cache of open directories. */ struct bftw_cache cache; - /** The queue of directories left to explore. */ + /** The queue of files left to explore. */ struct bftw_queue queue; /** The reader for the current directory. */ @@ -837,18 +836,18 @@ err: */ static int bftw_update_path(struct bftw_state *state) { struct bftw_reader *reader = &state->reader; - struct bftw_dir *dir = reader->dir; + struct bftw_file *file = reader->file; struct dirent *de = reader->de; size_t length; if (de) { - length = dir->nameoff + dir->namelen; - } else if (dir->depth == 0) { + length = file->nameoff + file->namelen; + } else if (file->depth == 0) { // Use exactly the string passed to bftw(), including any trailing slashes length = strlen(state->root); } else { // -1 to trim the trailing slash - length = dir->nameoff + dir->namelen - 1; + length = file->nameoff + file->namelen - 1; } if (dstrlen(reader->path) < length) { @@ -906,11 +905,11 @@ static bool bftw_need_stat(struct bftw_state *state) { */ static void bftw_prepare_visit(struct bftw_state *state) { struct bftw_reader *reader = &state->reader; - struct bftw_dir *dir = reader->dir; + struct bftw_file *file = reader->file; struct dirent *de = reader->de; struct BFTW *ftwbuf = &state->ftwbuf; - ftwbuf->path = dir ? reader->path : state->root; + ftwbuf->path = file ? reader->path : state->root; ftwbuf->root = state->root; ftwbuf->depth = 0; ftwbuf->visit = state->visit; @@ -920,18 +919,18 @@ static void bftw_prepare_visit(struct bftw_state *state) { ftwbuf->at_path = ftwbuf->path; ftwbuf->at_flags = AT_SYMLINK_NOFOLLOW; - if (dir) { - ftwbuf->nameoff = dir->nameoff; - ftwbuf->depth = dir->depth; + if (file) { + ftwbuf->nameoff = file->nameoff; + ftwbuf->depth = file->depth; if (de) { - ftwbuf->nameoff += dir->namelen; + ftwbuf->nameoff += file->namelen; ++ftwbuf->depth; - ftwbuf->at_fd = dir->fd; + ftwbuf->at_fd = file->fd; ftwbuf->at_path += ftwbuf->nameoff; } else { - bftw_dir_base(dir, &ftwbuf->at_fd, &ftwbuf->at_path); + bftw_file_base(file, &ftwbuf->at_fd, &ftwbuf->at_path); } } @@ -970,7 +969,7 @@ static void bftw_prepare_visit(struct bftw_state *state) { if (ftwbuf->typeflag == BFTW_DIR && (state->flags & BFTW_DETECT_CYCLES)) { const struct bfs_stat *statbuf = ftwbuf->statbuf; - for (const struct bftw_dir *parent = dir; parent; parent = parent->parent) { + for (const struct bftw_file *parent = file; parent; parent = parent->parent) { if (parent->depth == ftwbuf->depth) { continue; } @@ -987,7 +986,7 @@ static void bftw_prepare_visit(struct bftw_state *state) { * Invoke the callback. */ static enum bftw_action bftw_visit_path(struct bftw_state *state) { - if (state->reader.dir) { + if (state->reader.file) { if (bftw_update_path(state) != 0) { state->error = errno; return BFTW_STOP; @@ -1023,20 +1022,20 @@ static enum bftw_action bftw_visit_path(struct bftw_state *state) { * Push a new directory onto the queue. */ static int bftw_push(struct bftw_state *state, const char *name) { - struct bftw_dir *parent = state->reader.dir; - struct bftw_dir *dir = bftw_dir_new(&state->cache, parent, name); - if (!dir) { + struct bftw_file *parent = state->reader.file; + struct bftw_file *file = bftw_file_new(&state->cache, parent, name); + if (!file) { state->error = errno; return -1; } const struct bfs_stat *statbuf = state->ftwbuf.statbuf; if (statbuf) { - dir->dev = statbuf->dev; - dir->ino = statbuf->ino; + file->dev = statbuf->dev; + file->ino = statbuf->ino; } - bftw_queue_push(&state->queue, dir); + bftw_queue_push(&state->queue, file); return 0; } @@ -1045,15 +1044,15 @@ static int bftw_push(struct bftw_state *state, const char *name) { */ static struct bftw_reader *bftw_pop(struct bftw_state *state) { struct bftw_reader *reader = &state->reader; - struct bftw_dir *dir = bftw_queue_pop(&state->queue); - bftw_reader_open(reader, &state->cache, dir); + struct bftw_file *file = bftw_queue_pop(&state->queue); + bftw_reader_open(reader, &state->cache, file); return reader; } /** - * Finalize and free a directory we're done with. + * Finalize and free a file we're done with. */ -static enum bftw_action bftw_release_dir(struct bftw_state *state, struct bftw_dir *dir, bool do_visit) { +static enum bftw_action bftw_release_file(struct bftw_state *state, struct bftw_file *file, bool do_visit) { enum bftw_action ret = BFTW_CONTINUE; if (!(state->flags & BFTW_DEPTH)) { @@ -1062,23 +1061,23 @@ static enum bftw_action bftw_release_dir(struct bftw_state *state, struct bftw_d state->visit = BFTW_POST; - while (dir) { - bftw_dir_decref(&state->cache, dir); - if (dir->refcount > 0) { + while (file) { + bftw_file_decref(&state->cache, file); + if (file->refcount > 0) { break; } if (do_visit) { - state->reader.dir = dir; + state->reader.file = file; if (bftw_visit_path(state) == BFTW_STOP) { ret = BFTW_STOP; do_visit = false; } } - struct bftw_dir *parent = dir->parent; - bftw_dir_free(&state->cache, dir); - dir = parent; + struct bftw_file *parent = file->parent; + bftw_file_free(&state->cache, file); + file = parent; } state->visit = BFTW_PRE; @@ -1108,11 +1107,11 @@ static enum bftw_action bftw_release_reader(struct bftw_state *state, bool do_vi reader->error = 0; } - if (bftw_release_dir(state, reader->dir, do_visit) == BFTW_STOP) { + if (bftw_release_file(state, reader->file, do_visit) == BFTW_STOP) { ret = BFTW_STOP; } - reader->dir = NULL; + reader->file = NULL; return ret; } @@ -1125,15 +1124,15 @@ static enum bftw_action bftw_release_reader(struct bftw_state *state, bool do_vi */ static int bftw_state_destroy(struct bftw_state *state) { struct bftw_reader *reader = &state->reader; - if (reader->dir) { + if (reader->file) { bftw_release_reader(state, false); } bftw_reader_destroy(reader); struct bftw_queue *queue = &state->queue; while (queue->head) { - struct bftw_dir *dir = bftw_queue_pop(queue); - bftw_release_dir(state, dir, false); + struct bftw_file *file = bftw_queue_pop(queue); + bftw_release_file(state, file, false); } bftw_cache_destroy(&state->cache); @@ -1198,7 +1197,7 @@ int bftw(const char *path, const struct bftw_args *args) { const struct bfs_stat *statbuf = state.ftwbuf.statbuf; if ((args->flags & BFTW_XDEV) && statbuf - && statbuf->dev != reader->dir->dev) { + && statbuf->dev != reader->file->dev) { goto read; } |