]> Sergey Matveev's repositories - bfs.git/commitdiff
dir: Add a flags parameter to bfs_opendir()
authorTavian Barnes <tavianator@tavianator.com>
Mon, 16 Oct 2023 20:44:46 +0000 (16:44 -0400)
committerTavian Barnes <tavianator@tavianator.com>
Tue, 17 Oct 2023 16:33:39 +0000 (12:33 -0400)
src/bftw.c
src/dir.c
src/dir.h
src/eval.c
src/ioq.c
src/ioq.h

index 06a0085ea4ea75055ace362660e5b83df7776137..e2f1a660f4606c7ba752ca6e6f66b5d93941a456 100644 (file)
@@ -856,7 +856,7 @@ static int bftw_ioq_opendir(struct bftw_state *state, struct bftw_file *file) {
                goto unpin;
        }
 
-       if (ioq_opendir(state->ioq, dir, dfd, file->name, file) != 0) {
+       if (ioq_opendir(state->ioq, dir, dfd, file->name, 0, file) != 0) {
                goto free;
        }
 
@@ -1018,7 +1018,7 @@ static struct bfs_dir *bftw_file_opendir(struct bftw_state *state, struct bftw_f
                return NULL;
        }
 
-       if (bfs_opendir(dir, fd, NULL) != 0) {
+       if (bfs_opendir(dir, fd, NULL, 0) != 0) {
                bftw_freedir(cache, dir);
                return NULL;
        }
index a7423e9bd242017550dc2c5030b4e233ff64ceed..dee02e506fc1c0264b10863d9c849f8a8c268422 100644 (file)
--- a/src/dir.c
+++ b/src/dir.c
@@ -96,18 +96,26 @@ enum bfs_type bfs_mode_to_type(mode_t mode) {
        }
 }
 
+/**
+ * Private directory flags.
+ */
+enum {
+       /** We've reached the end of the directory. */
+       BFS_DIR_EOF = BFS_DIR_PRIVATE << 0,
+};
+
 struct bfs_dir {
+       unsigned int flags;
+
 #if BFS_USE_GETDENTS
-       alignas(sys_dirent) int fd;
+       int fd;
        unsigned short pos;
        unsigned short size;
-       // sys_dirent buf[];
+       alignas(sys_dirent) char buf[];
 #else
        DIR *dir;
        struct dirent *de;
 #endif
-
-       bool eof;
 };
 
 #if BFS_USE_GETDENTS
@@ -125,7 +133,7 @@ void bfs_dir_arena(struct arena *arena) {
        arena_init(arena, alignof(struct bfs_dir), DIR_SIZE);
 }
 
-int bfs_opendir(struct bfs_dir *dir, int at_fd, const char *at_path) {
+int bfs_opendir(struct bfs_dir *dir, int at_fd, const char *at_path, enum bfs_dir_flags flags) {
        int fd;
        if (at_path) {
                fd = openat(at_fd, at_path, O_RDONLY | O_CLOEXEC | O_DIRECTORY);
@@ -139,6 +147,8 @@ int bfs_opendir(struct bfs_dir *dir, int at_fd, const char *at_path) {
                return -1;
        }
 
+       dir->flags = flags;
+
 #if BFS_USE_GETDENTS
        dir->fd = fd;
        dir->pos = 0;
@@ -154,7 +164,6 @@ int bfs_opendir(struct bfs_dir *dir, int at_fd, const char *at_path) {
        dir->de = NULL;
 #endif
 
-       dir->eof = false;
        return 0;
 }
 
@@ -170,14 +179,14 @@ int bfs_polldir(struct bfs_dir *dir) {
 #if BFS_USE_GETDENTS
        if (dir->pos < dir->size) {
                return 1;
-       } else if (dir->eof) {
+       } else if (dir->flags & BFS_DIR_EOF) {
                return 0;
        }
 
        char *buf = (char *)(dir + 1);
        ssize_t size = bfs_getdents(dir->fd, buf, BUF_SIZE);
        if (size == 0) {
-               dir->eof = true;
+               dir->flags |= BFS_DIR_EOF;
                return 0;
        } else if (size < 0) {
                return -1;
@@ -194,7 +203,7 @@ int bfs_polldir(struct bfs_dir *dir) {
                if (size > 0) {
                        dir->size += size;
                } else if (size == 0) {
-                       dir->eof = true;
+                       dir->flags |= BFS_DIR_EOF;
                }
        }
 
@@ -202,7 +211,7 @@ int bfs_polldir(struct bfs_dir *dir) {
 #else // !BFS_USE_GETDENTS
        if (dir->de) {
                return 1;
-       } else if (dir->eof) {
+       } else if (dir->flags & BFS_DIR_EOF) {
                return 0;
        }
 
@@ -211,7 +220,7 @@ int bfs_polldir(struct bfs_dir *dir) {
        if (dir->de) {
                return 1;
        } else if (errno == 0) {
-               dir->eof = true;
+               dir->flags |= BFS_DIR_EOF;
                return 0;
        } else {
                return -1;
index 1137ff539ccf49bfa23c90b95c264ef1283fa187..7e0cbba8f5898d5d6b929730d56c49793e9f32fc 100644 (file)
--- a/src/dir.h
+++ b/src/dir.h
@@ -86,6 +86,14 @@ struct bfs_dir *bfs_allocdir(void);
  */
 void bfs_dir_arena(struct arena *arena);
 
+/**
+ * bfs_opendir() flags.
+ */
+enum bfs_dir_flags {
+       /** @internal Start of private flags. */
+       BFS_DIR_PRIVATE = 1 << 0,
+};
+
 /**
  * Open a directory.
  *
@@ -96,10 +104,12 @@ void bfs_dir_arena(struct arena *arena);
  * @param at_path
  *         The path of the directory to open, relative to at_fd.  Pass NULL to
  *         open at_fd itself.
+ * @param flags
+ *         Flags that control which directory entries are listed.
  * @return
  *         0 on success, or -1 on failure.
  */
-int bfs_opendir(struct bfs_dir *dir, int at_fd, const char *at_path);
+int bfs_opendir(struct bfs_dir *dir, int at_fd, const char *at_path, enum bfs_dir_flags flags);
 
 /**
  * Get the file descriptor for a directory.
index e0dd97ba6adc2942af176de039f0b2242fa17eff..adf7a0b92d787ca65b15bbbbbdfca17ccbac92b9 100644 (file)
@@ -427,7 +427,7 @@ bool eval_empty(const struct bfs_expr *expr, struct bfs_eval *state) {
                        return ret;
                }
 
-               if (bfs_opendir(dir, ftwbuf->at_fd, ftwbuf->at_path) != 0) {
+               if (bfs_opendir(dir, ftwbuf->at_fd, ftwbuf->at_path, 0) != 0) {
                        eval_report_error(state);
                        return ret;
                }
@@ -1517,8 +1517,8 @@ static int infer_fdlimit(const struct bfs_ctx *ctx, int limit) {
                goto done;
        }
 
-       if (bfs_opendir(dir, AT_FDCWD, "/proc/self/fd") != 0
-           && bfs_opendir(dir, AT_FDCWD, "/dev/fd") != 0) {
+       if (bfs_opendir(dir, AT_FDCWD, "/proc/self/fd", 0) != 0
+           && bfs_opendir(dir, AT_FDCWD, "/dev/fd", 0) != 0) {
                goto done;
        }
 
index 04b9c0d2c38587c2397c5b65a18f59deb8ade321..8c1bdbe29639d1e827ec2698ec6f1e57631b49e5 100644 (file)
--- a/src/ioq.c
+++ b/src/ioq.c
@@ -348,7 +348,7 @@ static void ioq_handle(struct ioq *ioq, struct ioq_ent *ent) {
                break;
 
        case IOQ_OPENDIR:
-               ret = bfs_opendir(ent->opendir.dir, ent->opendir.dfd, ent->opendir.path);
+               ret = bfs_opendir(ent->opendir.dir, ent->opendir.dfd, ent->opendir.path, ent->opendir.flags);
                if (ret == 0) {
                        bfs_polldir(ent->opendir.dir);
                }
@@ -505,7 +505,7 @@ static void ioq_ring_reap(struct ioq_ring_state *state) {
                                continue;
                        }
 
-                       ent->ret = bfs_opendir(ent->opendir.dir, fd, NULL);
+                       ent->ret = bfs_opendir(ent->opendir.dir, fd, NULL, ent->opendir.flags);
                        if (ent->ret == 0) {
                                // TODO: io_uring_prep_getdents()
                                bfs_polldir(ent->opendir.dir);
@@ -659,7 +659,7 @@ int ioq_close(struct ioq *ioq, int fd, void *ptr) {
        return 0;
 }
 
-int ioq_opendir(struct ioq *ioq, struct bfs_dir *dir, int dfd, const char *path, void *ptr) {
+int ioq_opendir(struct ioq *ioq, struct bfs_dir *dir, int dfd, const char *path, enum bfs_dir_flags flags, void *ptr) {
        struct ioq_ent *ent = ioq_request(ioq, IOQ_OPENDIR, ptr);
        if (!ent) {
                return -1;
@@ -669,6 +669,7 @@ int ioq_opendir(struct ioq *ioq, struct bfs_dir *dir, int dfd, const char *path,
        args->dir = dir;
        args->dfd = dfd;
        args->path = path;
+       args->flags = flags;
 
        ioqq_push(ioq->pending, ent);
        return 0;
index 99c18c20ea036bedb5ff5e4ddf729cca304f1f29..eab89ec010748c66fb75f7fecf81fd07e2f2575c 100644 (file)
--- a/src/ioq.h
+++ b/src/ioq.h
@@ -8,6 +8,7 @@
 #ifndef BFS_IOQ_H
 #define BFS_IOQ_H
 
+#include "dir.h"
 #include <stddef.h>
 
 /**
@@ -53,6 +54,7 @@ struct ioq_ent {
                        struct bfs_dir *dir;
                        int dfd;
                        const char *path;
+                       enum bfs_dir_flags flags;
                } opendir;
                /** ioq_closedir() args. */
                struct ioq_closedir {
@@ -103,12 +105,14 @@ int ioq_close(struct ioq *ioq, int fd, void *ptr);
  *         The base file descriptor.
  * @param path
  *         The path to open, relative to dfd.
+ * @param flags
+ *         Flags that control which directory entries are listed.
  * @param ptr
  *         An arbitrary pointer to associate with the request.
  * @return
  *         0 on success, or -1 on failure.
  */
-int ioq_opendir(struct ioq *ioq, struct bfs_dir *dir, int dfd, const char *path, void *ptr);
+int ioq_opendir(struct ioq *ioq, struct bfs_dir *dir, int dfd, const char *path, enum bfs_dir_flags flags, void *ptr);
 
 /**
  * Asynchronous bfs_closedir().