From fd0f8a3d42a5b59f471ba77df31c4e45ab9c01f3 Mon Sep 17 00:00:00 2001 From: Tavian Barnes Date: Fri, 7 Apr 2023 11:13:33 -0400 Subject: dir: Allow overriding BFS_GETDENTS --- src/dir.c | 41 +++++++++++++++++++++++------------------ 1 file changed, 23 insertions(+), 18 deletions(-) (limited to 'src/dir.c') diff --git a/src/dir.c b/src/dir.c index b92b7c2..2719c15 100644 --- a/src/dir.c +++ b/src/dir.c @@ -4,6 +4,7 @@ #include "dir.h" #include "bfstd.h" #include "config.h" +#include #include #include #include @@ -14,22 +15,17 @@ #include #include -#if __has_feature(memory_sanitizer) -# include -#endif - -#if __linux__ -# include - -/** Directory entry type for bfs_getdents() */ -typedef struct dirent64 sys_dirent; -#else -typedef struct dirent sys_dirent; +#ifndef BFS_GETDENTS +# define BFS_GETDENTS (__linux__ || __FreeBSD__) #endif -#define BFS_GETDENTS (__linux__ || __FreeBSD__) - #if BFS_GETDENTS +# if __has_feature(memory_sanitizer) +# include +# endif +# if __linux__ +# include +# endif /** getdents() syscall wrapper. */ static ssize_t bfs_getdents(int fd, void *buf, size_t size) { @@ -56,6 +52,13 @@ static ssize_t bfs_getdents(int fd, void *buf, size_t size) { #endif // BFS_GETDENTS +#if BFS_GETDENTS && __linux__ +/** Directory entry type for bfs_getdents() */ +typedef struct dirent64 sys_dirent; +#else +typedef struct dirent sys_dirent; +#endif + enum bfs_type bfs_mode_to_type(mode_t mode) { switch (mode & S_IFMT) { #ifdef S_IFBLK @@ -112,7 +115,6 @@ struct bfs_dir { // sys_dirent buf[]; #else DIR *dir; - struct dirent *de; #endif }; @@ -158,8 +160,6 @@ struct bfs_dir *bfs_opendir(int at_fd, const char *at_path) { free(dir); return NULL; } - - dir->de = NULL; #endif return dir; @@ -251,6 +251,7 @@ int bfs_closedir(struct bfs_dir *dir) { int ret = xclose(dir->fd); #else int ret = closedir(dir->dir); + assert(ret == 0 || errno != EBADF); #endif free(dir); return ret; @@ -260,10 +261,14 @@ int bfs_freedir(struct bfs_dir *dir) { #if BFS_GETDENTS int ret = dir->fd; free(dir); - return ret; +#elif __FreeBSD__ + int ret = fdclosedir(dir->dir); + free(dir); #else int ret = dup_cloexec(dirfd(dir->dir)); + int error = errno; bfs_closedir(dir); - return ret; + errno = error; #endif + return ret; } -- cgit v1.2.3