From 3c8233869d34713860c48b1230c3ea06b8767b88 Mon Sep 17 00:00:00 2001 From: Tavian Barnes Date: Sat, 22 Oct 2016 21:05:47 -0400 Subject: Implement -ignore_readdir_race. --- eval.c | 42 +++++++++++++++++++++++++----------------- 1 file changed, 25 insertions(+), 17 deletions(-) (limited to 'eval.c') diff --git a/eval.c b/eval.c index 4778b5d..f930bac 100644 --- a/eval.c +++ b/eval.c @@ -51,13 +51,24 @@ struct eval_state { struct stat statbuf; }; +/** + * Check if an error should be ignored. + */ +static bool eval_should_ignore(const struct eval_state *state, int error) { + return state->cmdline->ignore_races + && error == ENOENT + && state->ftwbuf->depth > 0; +} + /** * Report an error that occurs during evaluation. */ static void eval_error(struct eval_state *state) { - pretty_error(state->cmdline->stderr_colors, - "'%s': %s\n", state->ftwbuf->path, strerror(errno)); - state->ret = -1; + if (!eval_should_ignore(state, errno)) { + pretty_error(state->cmdline->stderr_colors, + "'%s': %s\n", state->ftwbuf->path, strerror(errno)); + state->ret = -1; + } } /** @@ -905,8 +916,6 @@ struct callback_args { const struct cmdline *cmdline; /** Eventual return value from eval_cmdline(). */ int ret; - /** The last error code seen. */ - int last_error; }; /** @@ -917,12 +926,6 @@ static enum bftw_action cmdline_callback(struct BFTW *ftwbuf, void *ptr) { const struct cmdline *cmdline = args->cmdline; - if (ftwbuf->typeflag == BFTW_ERROR) { - args->last_error = ftwbuf->error; - pretty_error(cmdline->stderr_colors, "'%s': %s\n", ftwbuf->path, strerror(ftwbuf->error)); - return BFTW_SKIP_SUBTREE; - } - struct eval_state state = { .ftwbuf = ftwbuf, .cmdline = cmdline, @@ -930,6 +933,15 @@ static enum bftw_action cmdline_callback(struct BFTW *ftwbuf, void *ptr) { .ret = args->ret, }; + if (ftwbuf->typeflag == BFTW_ERROR) { + if (!eval_should_ignore(&state, ftwbuf->error)) { + state.ret = -1; + pretty_error(cmdline->stderr_colors, "'%s': %s\n", ftwbuf->path, strerror(ftwbuf->error)); + } + state.action = BFTW_SKIP_SUBTREE; + goto done; + } + if (ftwbuf->depth >= cmdline->maxdepth) { state.action = BFTW_SKIP_SUBTREE; } @@ -948,6 +960,7 @@ static enum bftw_action cmdline_callback(struct BFTW *ftwbuf, void *ptr) { eval_expr(cmdline->expr, &state); } +done: if ((cmdline->debug & DEBUG_STAT) && ftwbuf->statbuf) { debug_stat(&state); } @@ -1024,14 +1037,9 @@ int eval_cmdline(const struct cmdline *cmdline) { }; for (struct root *root = cmdline->roots; root; root = root->next) { - args.last_error = 0; - if (bftw(root->path, cmdline_callback, nopenfd, cmdline->flags, &args) != 0) { args.ret = -1; - - if (errno != args.last_error) { - perror("bftw()"); - } + perror("bftw()"); } } -- cgit v1.2.3