From b2e69d3f76270fc4051801cac923307514184055 Mon Sep 17 00:00:00 2001 From: Tavian Barnes Date: Thu, 20 Dec 2018 17:06:27 -0500 Subject: stat: Unify bfs_stat_time() implementations --- eval.c | 26 ++++++++------------------ printf.c | 28 ++-------------------------- stat.c | 25 ++++++++++++++++++++++++- stat.h | 5 +++++ 4 files changed, 39 insertions(+), 45 deletions(-) diff --git a/eval.c b/eval.c index 5d71318..f636173 100644 --- a/eval.c +++ b/eval.c @@ -214,8 +214,10 @@ bool eval_capable(const struct expr *expr, struct eval_state *state) { * Get the given timespec field out of a stat buffer. */ static const struct timespec *eval_stat_time(const struct bfs_stat *statbuf, enum bfs_stat_field field, const struct eval_state *state) { - if (!(statbuf->mask & field)) { - const char *kind = ""; + const struct timespec *ret = bfs_stat_time(statbuf, field); + + if (!ret) { + const char *kind; switch (field) { case BFS_STAT_ATIME: kind = "access"; @@ -231,27 +233,15 @@ static const struct timespec *eval_stat_time(const struct bfs_stat *statbuf, enu break; default: assert(false); + kind = "???"; break; } - cfprintf(state->cmdline->cerr, "%{er}error: '%s': Couldn't get file %s time.%{rs}\n", state->ftwbuf->path, kind); + cfprintf(state->cmdline->cerr, "%{er}error: '%s': Couldn't get file %s time: %s%{rs}\n", state->ftwbuf->path, kind, strerror(errno)); *state->ret = EXIT_FAILURE; - return NULL; - } - - switch (field) { - case BFS_STAT_ATIME: - return &statbuf->atime; - case BFS_STAT_BTIME: - return &statbuf->btime; - case BFS_STAT_CTIME: - return &statbuf->ctime; - case BFS_STAT_MTIME: - return &statbuf->mtime; - default: - assert(false); - return NULL; } + + return ret; } /** diff --git a/printf.c b/printf.c index 1da0de7..4fc2dfb 100644 --- a/printf.c +++ b/printf.c @@ -76,37 +76,13 @@ static int bfs_printf_flush(FILE *file, const struct bfs_printf_directive *direc assert(ret >= 0 && ret < sizeof(buf)); \ (void)ret -/** - * Get a particular time field from a struct bfs_stat. - */ -static const struct timespec *get_time_field(const struct bfs_stat *statbuf, enum bfs_stat_field stat_field) { - if (!(statbuf->mask & stat_field)) { - errno = ENOTSUP; - return NULL; - } - - switch (stat_field) { - case BFS_STAT_ATIME: - return &statbuf->atime; - case BFS_STAT_BTIME: - return &statbuf->btime; - case BFS_STAT_CTIME: - return &statbuf->ctime; - case BFS_STAT_MTIME: - return &statbuf->mtime; - default: - assert(false); - return NULL; - } -} - /** %a, %c, %t: ctime() */ static int bfs_printf_ctime(FILE *file, const struct bfs_printf_directive *directive, const struct BFTW *ftwbuf) { // Not using ctime() itself because GNU find adds nanoseconds static const char *days[] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"}; static const char *months[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; - const struct timespec *ts = get_time_field(ftwbuf->statbuf, directive->stat_field); + const struct timespec *ts = bfs_stat_time(ftwbuf->statbuf, directive->stat_field); if (!ts) { return -1; } @@ -131,7 +107,7 @@ static int bfs_printf_ctime(FILE *file, const struct bfs_printf_directive *direc /** %A, %B/%W, %C, %T: strftime() */ static int bfs_printf_strftime(FILE *file, const struct bfs_printf_directive *directive, const struct BFTW *ftwbuf) { - const struct timespec *ts = get_time_field(ftwbuf->statbuf, directive->stat_field); + const struct timespec *ts = bfs_stat_time(ftwbuf->statbuf, directive->stat_field); if (!ts) { return -1; } diff --git a/stat.c b/stat.c index 8ce13e9..c567873 100644 --- a/stat.c +++ b/stat.c @@ -16,6 +16,7 @@ #include "stat.h" #include "util.h" +#include #include #include #include @@ -151,7 +152,7 @@ static int bfs_statx_impl(int at_fd, const char *at_path, int at_flags, enum bfs // Callers shouldn't have to check anything except the times const int guaranteed = STATX_BASIC_STATS ^ (STATX_ATIME | STATX_CTIME | STATX_MTIME); if ((xbuf.stx_mask & guaranteed) != guaranteed) { - errno = EINVAL; + errno = ENODATA; return -1; } @@ -268,3 +269,25 @@ int bfs_fstat(int fd, struct bfs_stat *buf) { } return ret; } + +const struct timespec *bfs_stat_time(const struct bfs_stat *buf, enum bfs_stat_field field) { + if (!(buf->mask & field)) { + errno = ENODATA; + return NULL; + } + + switch (field) { + case BFS_STAT_ATIME: + return &buf->atime; + case BFS_STAT_BTIME: + return &buf->btime; + case BFS_STAT_CTIME: + return &buf->ctime; + case BFS_STAT_MTIME: + return &buf->mtime; + default: + assert(false); + errno = EINVAL; + return NULL; + } +} diff --git a/stat.h b/stat.h index dc24cb4..4bad74e 100644 --- a/stat.h +++ b/stat.h @@ -108,4 +108,9 @@ int bfs_stat(int at_fd, const char *at_path, int at_flags, enum bfs_stat_flag fl */ int bfs_fstat(int fd, struct bfs_stat *buf); +/** + * Get a particular time field from a bfs_stat() buffer. + */ +const struct timespec *bfs_stat_time(const struct bfs_stat *buf, enum bfs_stat_field field); + #endif // BFS_STAT_H -- cgit v1.2.3