From a7e08e893eb796637ca2c53cd32a529f453ace12 Mon Sep 17 00:00:00 2001 From: Tavian Barnes Date: Mon, 14 Nov 2016 22:40:40 -0500 Subject: Check for readdir() errors everywhere. --- bftw.c | 16 ++-------------- eval.c | 20 ++++++++++++++++---- util.c | 10 ++++++++++ util.h | 6 ++++++ 4 files changed, 34 insertions(+), 18 deletions(-) diff --git a/bftw.c b/bftw.c index 630c643..e2bfcc6 100644 --- a/bftw.c +++ b/bftw.c @@ -22,6 +22,7 @@ #include "bftw.h" #include "dstring.h" +#include "util.h" #include #include #include @@ -867,19 +868,6 @@ static struct dircache_entry *bftw_add(struct bftw_state *state, const char *nam return entry; } -/** - * readdir() wrapper that makes error handling cleaner. - */ -static int bftw_readdir(DIR *dir, struct dirent **de) { - errno = 0; - *de = readdir(dir); - if (!*de && errno != 0) { - return -1; - } else { - return 0; - } -} - /** * Push a new entry onto the queue. */ @@ -1016,7 +1004,7 @@ int bftw(const char *path, bftw_fn *fn, int nopenfd, enum bftw_flags flags, void while (true) { struct dirent *de; - if (bftw_readdir(dir, &de) != 0) { + if (xreaddir(dir, &de) != 0) { goto dir_error; } if (!de) { diff --git a/eval.c b/eval.c index 1e88a93..80df040 100644 --- a/eval.c +++ b/eval.c @@ -498,14 +498,23 @@ bool eval_empty(const struct expr *expr, struct eval_state *state) { ret = true; - struct dirent *de; - while ((de = readdir(dir)) != NULL) { + while (true) { + struct dirent *de; + if (xreaddir(dir, &de) != 0) { + eval_error(state); + goto done_dir; + } + if (!de) { + break; + } + if (strcmp(de->d_name, ".") != 0 && strcmp(de->d_name, "..") != 0) { ret = false; break; } } + done_dir: closedir(dir); } else { const struct stat *statbuf = fill_statbuf(state); @@ -1038,8 +1047,11 @@ static int infer_fdlimit(const struct cmdline *cmdline) { // Account for 'dir' itself nopen = -1; - struct dirent *de; - while ((de = readdir(dir)) != NULL) { + while (true) { + struct dirent *de; + if (xreaddir(dir, &de) != 0 || !de) { + break; + } if (strcmp(de->d_name, ".") != 0 && strcmp(de->d_name, "..") != 0) { ++nopen; } diff --git a/util.c b/util.c index e0f6177..aef5fbb 100644 --- a/util.c +++ b/util.c @@ -17,6 +17,16 @@ #include #include +int xreaddir(DIR *dir, struct dirent **de) { + errno = 0; + *de = readdir(dir); + if (!*de && errno != 0) { + return -1; + } else { + return 0; + } +} + bool isopen(int fd) { return fcntl(fd, F_GETFD) >= 0 || errno != EBADF; } diff --git a/util.h b/util.h index c3b3dbe..fbcadbd 100644 --- a/util.h +++ b/util.h @@ -12,8 +12,14 @@ #ifndef BFS_UTIL_H #define BFS_UTIL_H +#include #include +/** + * readdir() wrapper that makes error handling cleaner. + */ +int xreaddir(DIR *dir, struct dirent **de); + /** * Check if a file descriptor is open. */ -- cgit v1.2.3