summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTavian Barnes <tavianator@tavianator.com>2016-11-14 22:40:40 -0500
committerTavian Barnes <tavianator@tavianator.com>2016-11-14 22:40:40 -0500
commita7e08e893eb796637ca2c53cd32a529f453ace12 (patch)
tree73f6bdc3e00baab465b5b90e963af94391f6d984
parent196cf9f617ca17acec75eafbcd9e5e7989752dcb (diff)
downloadbfs-a7e08e893eb796637ca2c53cd32a529f453ace12.tar.xz
Check for readdir() errors everywhere.
-rw-r--r--bftw.c16
-rw-r--r--eval.c20
-rw-r--r--util.c10
-rw-r--r--util.h6
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 <assert.h>
#include <dirent.h>
#include <errno.h>
@@ -868,19 +869,6 @@ static struct dircache_entry *bftw_add(struct bftw_state *state, const char *nam
}
/**
- * 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.
*/
static int bftw_push(struct bftw_state *state, const char *name) {
@@ -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 <sys/types.h>
#include <unistd.h>
+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,9 +12,15 @@
#ifndef BFS_UTIL_H
#define BFS_UTIL_H
+#include <dirent.h>
#include <stdbool.h>
/**
+ * readdir() wrapper that makes error handling cleaner.
+ */
+int xreaddir(DIR *dir, struct dirent **de);
+
+/**
* Check if a file descriptor is open.
*/
bool isopen(int fd);