summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTavian Barnes <tavianator@tavianator.com>2016-02-12 14:42:46 -0500
committerTavian Barnes <tavianator@tavianator.com>2016-02-12 14:42:46 -0500
commit25648b2999b918dd1ebd9faa1f8dbff705a7a46c (patch)
tree69ae3049b96552e171a5123ae4e63b40e699b6ba
parent177810c910348f9958bff22ec9c543637a2d6e8b (diff)
downloadbfs-25648b2999b918dd1ebd9faa1f8dbff705a7a46c.tar.xz
Report failures that happen inside predicates.
-rw-r--r--bfs.h2
-rw-r--r--eval.c35
2 files changed, 30 insertions, 7 deletions
diff --git a/bfs.h b/bfs.h
index c20fa17..82edd98 100644
--- a/bfs.h
+++ b/bfs.h
@@ -138,7 +138,7 @@ struct cmdline *parse_cmdline(int argc, char *argv[]);
/**
* Evaluate the command line.
*/
-int eval_cmdline(struct cmdline *cl);
+int eval_cmdline(const struct cmdline *cl);
/**
* Free the parsed command line.
diff --git a/eval.c b/eval.c
index 10379a3..0698857 100644
--- a/eval.c
+++ b/eval.c
@@ -29,6 +29,8 @@ struct eval_state {
const struct cmdline *cl;
/** The bftw() callback return value. */
enum bftw_action action;
+ /** The eval_cmdline() return value. */
+ int ret;
/** A stat() buffer, if necessary. */
struct stat statbuf;
};
@@ -42,6 +44,7 @@ static const struct stat *fill_statbuf(struct eval_state *state) {
if (fstatat(ftwbuf->at_fd, ftwbuf->at_path, &state->statbuf, AT_SYMLINK_NOFOLLOW) == 0) {
ftwbuf->statbuf = &state->statbuf;
} else {
+ state->ret = -1;
perror("fstatat()");
}
}
@@ -211,12 +214,14 @@ bool eval_empty(const struct expr *expr, struct eval_state *state) {
if (ftwbuf->typeflag == BFTW_DIR) {
int dfd = openat(ftwbuf->at_fd, ftwbuf->at_path, O_DIRECTORY);
if (dfd < 0) {
+ state->ret = -1;
perror("openat()");
goto done;
}
DIR *dir = fdopendir(dfd);
if (!dir) {
+ state->ret = -1;
perror("fdopendir()");
close(dfd);
goto done;
@@ -411,10 +416,22 @@ static int infer_nopenfd() {
}
/**
+ * Type passed as the argument to the bftw() callback.
+ */
+struct callback_args {
+ /** The parsed command line. */
+ const struct cmdline *cl;
+ /** Eventual return value from eval_cmdline(). */
+ int ret;
+};
+
+/**
* bftw() callback.
*/
static enum bftw_action cmdline_callback(struct BFTW *ftwbuf, void *ptr) {
- const struct cmdline *cl = ptr;
+ struct callback_args *args = ptr;
+
+ const struct cmdline *cl = args->cl;
if (ftwbuf->typeflag == BFTW_ERROR) {
print_error(cl->colors, ftwbuf->path, ftwbuf->error);
@@ -425,6 +442,7 @@ static enum bftw_action cmdline_callback(struct BFTW *ftwbuf, void *ptr) {
.ftwbuf = ftwbuf,
.cl = cl,
.action = BFTW_CONTINUE,
+ .ret = args->ret,
};
if (ftwbuf->depth >= cl->maxdepth) {
@@ -445,22 +463,27 @@ static enum bftw_action cmdline_callback(struct BFTW *ftwbuf, void *ptr) {
cl->expr->eval(cl->expr, &state);
}
+ args->ret = state.ret;
return state.action;
}
/**
* Evaluate the command line.
*/
-int eval_cmdline(struct cmdline *cl) {
- int ret = 0;
+int eval_cmdline(const struct cmdline *cl) {
int nopenfd = infer_nopenfd();
+ struct callback_args args = {
+ .cl = cl,
+ .ret = 0,
+ };
+
for (size_t i = 0; i < cl->nroots; ++i) {
- if (bftw(cl->roots[i], cmdline_callback, nopenfd, cl->flags, cl) != 0) {
- ret = -1;
+ if (bftw(cl->roots[i], cmdline_callback, nopenfd, cl->flags, &args) != 0) {
+ args.ret = -1;
perror("bftw()");
}
}
- return ret;
+ return args.ret;
}