diff options
Diffstat (limited to 'src/eval.c')
-rw-r--r-- | src/eval.c | 56 |
1 files changed, 35 insertions, 21 deletions
@@ -5,10 +5,11 @@ * Implementation of all the primary expressions. */ -#include "prelude.h" #include "eval.h" + #include "atomic.h" #include "bar.h" +#include "bfs.h" #include "bfstd.h" #include "bftw.h" #include "color.h" @@ -27,11 +28,13 @@ #include "stat.h" #include "trie.h" #include "xregex.h" + #include <errno.h> #include <fcntl.h> #include <fnmatch.h> #include <grp.h> #include <pwd.h> +#include <signal.h> #include <stdarg.h> #include <stdint.h> #include <stdio.h> @@ -53,6 +56,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; }; @@ -60,12 +65,18 @@ struct bfs_eval { /** * Print an error message. */ -attr(printf(2, 3)) +_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); @@ -269,10 +280,10 @@ bool eval_time(const struct bfs_expr *expr, struct bfs_eval *state) { switch (expr->time_unit) { case BFS_DAYS: diff /= 60 * 24; - fallthru; + _fallthrough; case BFS_MINUTES: diff /= 60; - fallthru; + _fallthrough; case BFS_SECONDS: break; } @@ -1014,25 +1025,23 @@ bool eval_xtype(const struct bfs_expr *expr, struct bfs_eval *state) { } } -#if _POSIX_MONOTONIC_CLOCK > 0 -# define BFS_CLOCK CLOCK_MONOTONIC -#elif _POSIX_TIMERS > 0 -# define BFS_CLOCK CLOCK_REALTIME -#endif - /** - * Call clock_gettime(), if available. + * clock_gettime() wrapper. */ static int eval_gettime(struct bfs_eval *state, struct timespec *ts) { -#ifdef BFS_CLOCK - int ret = clock_gettime(BFS_CLOCK, ts); + clockid_t clock = CLOCK_REALTIME; + +#if defined(_POSIX_MONOTONIC_CLOCK) && _POSIX_MONOTONIC_CLOCK >= 0 + if (sysoption(MONOTONIC_CLOCK) > 0) { + clock = CLOCK_MONOTONIC; + } +#endif + + int ret = clock_gettime(clock, ts); if (ret != 0) { bfs_warning(state->ctx, "%pP: clock_gettime(): %s.\n", state->ftwbuf, errstr()); } return ret; -#else - return -1; -#endif } /** @@ -1382,8 +1391,6 @@ struct callback_args { struct bfs_bar *bar; /** The time of the last status update. */ struct timespec last_status; - /** SIGINFO hook. */ - struct sighook *info_hook; /** Flag set by SIGINFO hook. */ atomic bool info_flag; @@ -1393,6 +1400,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; }; @@ -1411,6 +1420,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 @@ -1672,7 +1682,7 @@ int bfs_eval(struct bfs_ctx *ctx) { #else int siginfo = SIGUSR1; #endif - args.info_hook = sighook(siginfo, eval_siginfo, &args, SH_CONTINUE); + struct sighook *info_hook = sighook(siginfo, eval_siginfo, &args, SH_CONTINUE); struct trie seen; if (ctx->unique) { @@ -1741,8 +1751,12 @@ int bfs_eval(struct bfs_ctx *ctx) { trie_destroy(&seen); } - sigunhook(args.info_hook); + sigunhook(info_hook); bfs_bar_hide(args.bar); + if (ctx->ignore_errors && args.nerrors > 0) { + bfs_warning(ctx, "Suppressed errors: %zu\n", args.nerrors); + } + return args.ret; } |