summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--bftw.c397
1 files changed, 198 insertions, 199 deletions
diff --git a/bftw.c b/bftw.c
index 4f94a55..717ffab 100644
--- a/bftw.c
+++ b/bftw.c
@@ -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;
}