summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTavian Barnes <tavianator@tavianator.com>2018-12-20 17:06:27 -0500
committerTavian Barnes <tavianator@tavianator.com>2018-12-20 17:06:27 -0500
commitb2e69d3f76270fc4051801cac923307514184055 (patch)
tree6dbfd40393a437ede929ab1748520a050e593b02
parent5bec8030c77b735147cdf73359bc8f91b19e28fb (diff)
downloadbfs-b2e69d3f76270fc4051801cac923307514184055.tar.xz
stat: Unify bfs_stat_time() implementations
-rw-r--r--eval.c26
-rw-r--r--printf.c28
-rw-r--r--stat.c25
-rw-r--r--stat.h5
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 <assert.h>
#include <errno.h>
#include <fcntl.h>
#include <stdbool.h>
@@ -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