diff options
Diffstat (limited to 'src/dir.h')
-rw-r--r-- | src/dir.h | 89 |
1 files changed, 68 insertions, 21 deletions
@@ -1,18 +1,5 @@ -/**************************************************************************** - * bfs * - * Copyright (C) 2021 Tavian Barnes <tavianator@tavianator.com> * - * * - * Permission to use, copy, modify, and/or distribute this software for any * - * purpose with or without fee is hereby granted. * - * * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - ****************************************************************************/ +// Copyright © Tavian Barnes <tavianator@tavianator.com> +// SPDX-License-Identifier: 0BSD /** * Directories and their contents. @@ -21,9 +8,18 @@ #ifndef BFS_DIR_H #define BFS_DIR_H +#include "prelude.h" #include <sys/types.h> /** + * Whether the implementation uses the getdents() syscall directly, rather than + * libc's readdir(). + */ +#if !defined(BFS_USE_GETDENTS) && (__linux__ || __FreeBSD__) +# define BFS_USE_GETDENTS (BFS_HAS_GETDENTS || BFS_HAS_GETDENTS64 | BFS_HAS_GETDENTS64_SYSCALL) +#endif + +/** * A directory. */ struct bfs_dir; @@ -74,17 +70,49 @@ struct bfs_dirent { }; /** + * Allocate space for a directory. + * + * @return + * An allocated, unopen directory, or NULL on failure. + */ +struct bfs_dir *bfs_allocdir(void); + +struct arena; + +/** + * Initialize an arena for directories. + * + * @param arena + * The arena to initialize. + */ +void bfs_dir_arena(struct arena *arena); + +/** + * bfs_opendir() flags. + */ +enum bfs_dir_flags { + /** Include whiteouts in the results. */ + BFS_DIR_WHITEOUTS = 1 << 0, + /** @internal Start of private flags. */ + BFS_DIR_PRIVATE = 1 << 1, +}; + +/** * Open a directory. * + * @param dir + * The allocated directory. * @param at_fd * The base directory for path resolution. * @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 - * The opened directory, or NULL on failure. + * 0 on success, or -1 on failure. */ -struct bfs_dir *bfs_opendir(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. @@ -92,6 +120,16 @@ struct bfs_dir *bfs_opendir(int at_fd, const char *at_path); int bfs_dirfd(const struct bfs_dir *dir); /** + * Performs any I/O necessary for the next bfs_readdir() call. + * + * @param dir + * The directory to poll. + * @return + * 1 on success, 0 on EOF, or -1 on failure. + */ +int bfs_polldir(struct bfs_dir *dir); + +/** * Read a directory entry. * * @param dir @@ -112,13 +150,22 @@ int bfs_readdir(struct bfs_dir *dir, struct bfs_dirent *de); int bfs_closedir(struct bfs_dir *dir); /** - * Free a directory, keeping an open file descriptor to it. + * Whether the bfs_unwrapdir() function is supported. + */ +#ifndef BFS_USE_UNWRAPDIR +# define BFS_USE_UNWRAPDIR (BFS_USE_GETDENTS || BFS_HAS_FDCLOSEDIR) +#endif + +#if BFS_USE_UNWRAPDIR +/** + * Detach the file descriptor from an open directory. * * @param dir - * The directory to free. + * The directory to detach. * @return - * The file descriptor on success, or -1 on failure. + * The file descriptor of the directory. */ -int bfs_freedir(struct bfs_dir *dir); +int bfs_unwrapdir(struct bfs_dir *dir); +#endif #endif // BFS_DIR_H |