From c3f52a2e3c22a8e05b60f94b8344501b14e87794 Mon Sep 17 00:00:00 2001 From: Tavian Barnes Date: Fri, 16 Aug 2024 09:24:30 -0400 Subject: New -noerror option to suppress error messages Closes: https://github.com/tavianator/bfs/issues/142 --- completions/bfs.bash | 1 + completions/bfs.fish | 1 + completions/bfs.zsh | 1 + docs/CHANGELOG.md | 3 +++ docs/bfs.1 | 3 +++ src/ctx.h | 2 ++ src/eval.c | 17 ++++++++++++++++- src/parse.c | 11 +++++++++++ 8 files changed, 38 insertions(+), 1 deletion(-) diff --git a/completions/bfs.bash b/completions/bfs.bash index 6fd82c8..0dd39f4 100644 --- a/completions/bfs.bash +++ b/completions/bfs.bash @@ -99,6 +99,7 @@ _bfs() { -ignore_readdir_race -mount -nocolor + -noerror -noignore_readdir_race -noleaf -nowarn diff --git a/completions/bfs.fish b/completions/bfs.fish index 24b0ad9..0b846f8 100644 --- a/completions/bfs.fish +++ b/completions/bfs.fish @@ -43,6 +43,7 @@ complete -c bfs -o noignore_readdir_race -d "Report an error if the file tree is complete -c bfs -o maxdepth -d "Ignore files deeper than specified number" -x complete -c bfs -o mindepth -d "Ignore files shallower than specified number" -x complete -c bfs -o mount -d "Don't descend into other mount points" +complete -c bfs -o noerror -d "Ignore any errors that occur during traversal" complete -c bfs -o nohidden -d "Exclude hidden files and directories" complete -c bfs -o noleaf -d "Ignored; for compatibility with GNU find" complete -c bfs -o regextype -d "Use specified flavored regex" -a $regex_type_comp -x diff --git a/completions/bfs.zsh b/completions/bfs.zsh index 432ab8c..3524d30 100644 --- a/completions/bfs.zsh +++ b/completions/bfs.zsh @@ -42,6 +42,7 @@ args=( '*-maxdepth[ignore files deeper than N]:maximum search depth' '*-mindepth[ignore files shallower than N]:minimum search depth' "*-mount[don't descend into other mount points]" + '*-noerror[ignore any errors that occur during traversal]' '*-nohidden[exclude hidden files]' '*-noleaf[ignored, for compatibility with GNU find]' '-regextype[type of regex to use, default posix-basic]:regexp syntax:(help posix-basic posix-extended ed emacs grep sed)' diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 358bc5d..aeaa7cc 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -16,6 +16,9 @@ For example, `bfs -newermt @946684800` will print files modified since January 1, 2000 (UTC). ([`c6bb003`](https://github.com/tavianator/bfs/commit/c6bb003b8882e9a16941f5803d072ec1cb728318)) +- The new `-noerror` option suppresses all error messages during traversal. + ([#142](https://github.com/tavianator/bfs/issues/142)) + ### Changes - `-mount` now excludes mount points entirely, to comply with the recently published POSIX 2024 standard. diff --git a/docs/bfs.1 b/docs/bfs.1 index 22dbe35..dc3b7b0 100644 --- a/docs/bfs.1 +++ b/docs/bfs.1 @@ -320,6 +320,9 @@ Don't descend into other mount points (same as .B \-xdev for now, but will skip mount points entirely in the future). .TP +.B \-noerror +Ignore any errors that occur during traversal. +.TP .B \-nohidden Exclude hidden files and directories. .TP diff --git a/src/ctx.h b/src/ctx.h index c7ebc20..4ca4a34 100644 --- a/src/ctx.h +++ b/src/ctx.h @@ -75,6 +75,8 @@ struct bfs_ctx { bool interactive; /** Whether to print warnings (-warn/-nowarn). */ bool warn; + /** Whether to report errors (-noerror). */ + bool ignore_errors; /** Whether any dangerous actions (-delete/-exec) are present. */ bool dangerous; diff --git a/src/eval.c b/src/eval.c index d139ed3..9676cf3 100644 --- a/src/eval.c +++ b/src/eval.c @@ -53,6 +53,8 @@ struct bfs_eval { enum bftw_action action; /** The bfs_eval() return value. */ int *ret; + /** The number of errors that have occurred. */ + size_t *nerrors; /** Whether to quit immediately. */ bool quit; }; @@ -62,10 +64,16 @@ struct bfs_eval { */ _printf(2, 3) static void eval_error(struct bfs_eval *state, const char *format, ...) { + const struct bfs_ctx *ctx = state->ctx; + + ++*state->nerrors; + if (ctx->ignore_errors) { + return; + } + // By POSIX, any errors should be accompanied by a non-zero exit status *state->ret = EXIT_FAILURE; - const struct bfs_ctx *ctx = state->ctx; CFILE *cerr = ctx->cerr; bfs_error(ctx, "%pP: ", state->ftwbuf); @@ -1389,6 +1397,8 @@ struct callback_args { /** The set of seen files. */ struct trie *seen; + /** The number of errors that have occurred. */ + size_t nerrors; /** Eventual return value from bfs_eval(). */ int ret; }; @@ -1407,6 +1417,7 @@ static enum bftw_action eval_callback(const struct BFTW *ftwbuf, void *ptr) { state.ctx = ctx; state.action = BFTW_CONTINUE; state.ret = &args->ret; + state.nerrors = &args->nerrors; state.quit = false; // Check whether SIGINFO was delivered and show/hide the bar @@ -1740,5 +1751,9 @@ int bfs_eval(struct bfs_ctx *ctx) { sigunhook(info_hook); bfs_bar_hide(args.bar); + if (args.nerrors > 0) { + bfs_warning(ctx, "suppressed errors: %zu\n", args.nerrors); + } + return args.ret; } diff --git a/src/parse.c b/src/parse.c index ddb67aa..fe0c10d 100644 --- a/src/parse.c +++ b/src/parse.c @@ -1816,6 +1816,14 @@ static struct bfs_expr *parse_newerxy(struct bfs_parser *parser, int arg1, int a return expr; } +/** + * Parse -noerror. + */ +static struct bfs_expr *parse_noerror(struct bfs_parser *parser, int arg1, int arg2) { + parser->ctx->ignore_errors = true; + return parse_nullary_option(parser); +} + /** * Parse -nogroup. */ @@ -2759,6 +2767,8 @@ static struct bfs_expr *parse_help(struct bfs_parser *parser, int arg1, int arg2 cfprintf(cout, " ${blu}-mount${rs}\n"); cfprintf(cout, " Don't descend into other mount points (same as ${blu}-xdev${rs} for now, but will\n"); cfprintf(cout, " skip mount points entirely in the future)\n"); + cfprintf(cout, " ${blu}-noerror${rs}\n"); + cfprintf(cout, " Ignore any errors that occur during traversal\n"); cfprintf(cout, " ${blu}-nohidden${rs}\n"); cfprintf(cout, " Exclude hidden files\n"); cfprintf(cout, " ${blu}-noleaf${rs}\n"); @@ -3053,6 +3063,7 @@ static const struct table_entry parse_table[] = { {"-newer", BFS_TEST, parse_newer, BFS_STAT_MTIME}, {"-newer", BFS_TEST, parse_newerxy, .prefix = true}, {"-nocolor", BFS_OPTION, parse_color, false}, + {"-noerror", BFS_OPTION, parse_noerror}, {"-nogroup", BFS_TEST, parse_nogroup}, {"-nohidden", BFS_TEST, parse_nohidden}, {"-noignore_readdir_race", BFS_OPTION, parse_ignore_races, false}, -- cgit v1.2.3