From 50432108fb3ef826301626b94c5e82ad2ab2bd75 Mon Sep 17 00:00:00 2001 From: Tavian Barnes Date: Mon, 8 Jan 2018 21:43:23 -0500 Subject: stat: New wrapper around the stat() family This lets bfs transparently support the new statx() system call on Linux, giving it access to file birth times. --- printf.c | 92 +++++++++++++++++++++++++++++++++++----------------------------- 1 file changed, 50 insertions(+), 42 deletions(-) (limited to 'printf.c') diff --git a/printf.c b/printf.c index 2d48cb6..27d9521 100644 --- a/printf.c +++ b/printf.c @@ -20,6 +20,7 @@ #include "dstring.h" #include "expr.h" #include "mtab.h" +#include "stat.h" #include "util.h" #include #include @@ -29,7 +30,6 @@ #include #include #include -#include #include typedef int bfs_printf_fn(FILE *file, const struct bfs_printf_directive *directive, const struct BFTW *ftwbuf); @@ -42,8 +42,8 @@ struct bfs_printf_directive { bfs_printf_fn *fn; /** String data associated with this directive. */ char *str; - /** The time field to print. */ - enum time_field time_field; + /** The stat field to print. */ + enum bfs_stat_field stat_field; /** Character data associated with this directive. */ char c; /** The current mount table. */ @@ -77,22 +77,22 @@ static int bfs_printf_flush(FILE *file, const struct bfs_printf_directive *direc (void)ret /** - * Get a particular time field from a struct stat. + * Get a particular time field from a struct bfs_stat. */ -static const struct timespec *get_time_field(const struct stat *statbuf, enum time_field time_field) { - switch (time_field) { - case ATIME: - return &statbuf->st_atim; - case CTIME: - return &statbuf->st_ctim; - case MTIME: - return &statbuf->st_mtim; - -#ifdef BFS_HAVE_ST_BIRTHTIM - case BTIME: - return &statbuf->st_birthtim; -#endif +static const struct timespec *get_time_field(const struct bfs_stat *statbuf, enum bfs_stat_field stat_field) { + if (!(statbuf->mask & stat_field)) { + 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; @@ -105,7 +105,11 @@ static int bfs_printf_ctime(FILE *file, const struct bfs_printf_directive *direc 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->time_field); + const struct timespec *ts = get_time_field(ftwbuf->statbuf, directive->stat_field); + if (!ts) { + return -1; + } + struct tm tm; if (xlocaltime(&ts->tv_sec, &tm) != 0) { return -1; @@ -126,7 +130,11 @@ static int bfs_printf_ctime(FILE *file, const struct bfs_printf_directive *direc /** %A, %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->time_field); + const struct timespec *ts = get_time_field(ftwbuf->statbuf, directive->stat_field); + if (!ts) { + return -1; + } + struct tm tm; if (xlocaltime(&ts->tv_sec, &tm) != 0) { return -1; @@ -175,7 +183,7 @@ static int bfs_printf_strftime(FILE *file, const struct bfs_printf_directive *di /** %b: blocks */ static int bfs_printf_b(FILE *file, const struct bfs_printf_directive *directive, const struct BFTW *ftwbuf) { - BFS_PRINTF_BUF(buf, "%ju", (uintmax_t)ftwbuf->statbuf->st_blocks); + BFS_PRINTF_BUF(buf, "%ju", (uintmax_t)ftwbuf->statbuf->blocks); return fprintf(file, directive->str, buf); } @@ -186,7 +194,7 @@ static int bfs_printf_d(FILE *file, const struct bfs_printf_directive *directive /** %D: device */ static int bfs_printf_D(FILE *file, const struct bfs_printf_directive *directive, const struct BFTW *ftwbuf) { - BFS_PRINTF_BUF(buf, "%ju", (uintmax_t)ftwbuf->statbuf->st_dev); + BFS_PRINTF_BUF(buf, "%ju", (uintmax_t)ftwbuf->statbuf->dev); return fprintf(file, directive->str, buf); } @@ -203,13 +211,13 @@ static int bfs_printf_F(FILE *file, const struct bfs_printf_directive *directive /** %G: gid */ static int bfs_printf_G(FILE *file, const struct bfs_printf_directive *directive, const struct BFTW *ftwbuf) { - BFS_PRINTF_BUF(buf, "%ju", (uintmax_t)ftwbuf->statbuf->st_gid); + BFS_PRINTF_BUF(buf, "%ju", (uintmax_t)ftwbuf->statbuf->gid); return fprintf(file, directive->str, buf); } /** %g: group name */ static int bfs_printf_g(FILE *file, const struct bfs_printf_directive *directive, const struct BFTW *ftwbuf) { - struct group *grp = getgrgid(ftwbuf->statbuf->st_gid); + struct group *grp = getgrgid(ftwbuf->statbuf->gid); if (!grp) { return bfs_printf_G(file, directive, ftwbuf); } @@ -251,13 +259,13 @@ static int bfs_printf_H(FILE *file, const struct bfs_printf_directive *directive /** %i: inode */ static int bfs_printf_i(FILE *file, const struct bfs_printf_directive *directive, const struct BFTW *ftwbuf) { - BFS_PRINTF_BUF(buf, "%ju", (uintmax_t)ftwbuf->statbuf->st_ino); + BFS_PRINTF_BUF(buf, "%ju", (uintmax_t)ftwbuf->statbuf->ino); return fprintf(file, directive->str, buf); } /** %k: 1K blocks */ static int bfs_printf_k(FILE *file, const struct bfs_printf_directive *directive, const struct BFTW *ftwbuf) { - BFS_PRINTF_BUF(buf, "%ju", (uintmax_t)(ftwbuf->statbuf->st_blocks + 1)/2); + BFS_PRINTF_BUF(buf, "%ju", (uintmax_t)(ftwbuf->statbuf->blocks + 1)/2); return fprintf(file, directive->str, buf); } @@ -279,19 +287,19 @@ static int bfs_printf_l(FILE *file, const struct bfs_printf_directive *directive /** %m: mode */ static int bfs_printf_m(FILE *file, const struct bfs_printf_directive *directive, const struct BFTW *ftwbuf) { - return fprintf(file, directive->str, (unsigned int)(ftwbuf->statbuf->st_mode & 07777)); + return fprintf(file, directive->str, (unsigned int)(ftwbuf->statbuf->mode & 07777)); } /** %M: symbolic mode */ static int bfs_printf_M(FILE *file, const struct bfs_printf_directive *directive, const struct BFTW *ftwbuf) { char buf[11]; - format_mode(ftwbuf->statbuf->st_mode, buf); + format_mode(ftwbuf->statbuf->mode, buf); return fprintf(file, directive->str, buf); } /** %n: link count */ static int bfs_printf_n(FILE *file, const struct bfs_printf_directive *directive, const struct BFTW *ftwbuf) { - BFS_PRINTF_BUF(buf, "%ju", (uintmax_t)ftwbuf->statbuf->st_nlink); + BFS_PRINTF_BUF(buf, "%ju", (uintmax_t)ftwbuf->statbuf->nlink); return fprintf(file, directive->str, buf); } @@ -311,25 +319,25 @@ static int bfs_printf_P(FILE *file, const struct bfs_printf_directive *directive /** %s: size */ static int bfs_printf_s(FILE *file, const struct bfs_printf_directive *directive, const struct BFTW *ftwbuf) { - BFS_PRINTF_BUF(buf, "%ju", (uintmax_t)ftwbuf->statbuf->st_size); + BFS_PRINTF_BUF(buf, "%ju", (uintmax_t)ftwbuf->statbuf->size); return fprintf(file, directive->str, buf); } /** %S: sparseness */ static int bfs_printf_S(FILE *file, const struct bfs_printf_directive *directive, const struct BFTW *ftwbuf) { - double sparsity = 512.0 * ftwbuf->statbuf->st_blocks / ftwbuf->statbuf->st_size; + double sparsity = 512.0 * ftwbuf->statbuf->blocks / ftwbuf->statbuf->size; return fprintf(file, directive->str, sparsity); } /** %U: uid */ static int bfs_printf_U(FILE *file, const struct bfs_printf_directive *directive, const struct BFTW *ftwbuf) { - BFS_PRINTF_BUF(buf, "%ju", (uintmax_t)ftwbuf->statbuf->st_uid); + BFS_PRINTF_BUF(buf, "%ju", (uintmax_t)ftwbuf->statbuf->uid); return fprintf(file, directive->str, buf); } /** %u: user name */ static int bfs_printf_u(FILE *file, const struct bfs_printf_directive *directive, const struct BFTW *ftwbuf) { - struct passwd *pwd = getpwuid(ftwbuf->statbuf->st_uid); + struct passwd *pwd = getpwuid(ftwbuf->statbuf->uid); if (!pwd) { return bfs_printf_U(file, directive, ftwbuf); } @@ -374,9 +382,9 @@ static int bfs_printf_Y(FILE *file, const struct bfs_printf_directive *directive const char *type = "U"; - struct stat sb; - if (fstatat(ftwbuf->at_fd, ftwbuf->at_path, &sb, 0) == 0) { - type = bfs_printf_type(mode_to_typeflag(sb.st_mode)); + struct bfs_stat sb; + if (bfs_stat(ftwbuf->at_fd, ftwbuf->at_path, 0, 0, &sb) == 0) { + type = bfs_printf_type(mode_to_typeflag(sb.mode)); } else { switch (errno) { case ELOOP: @@ -418,7 +426,7 @@ static struct bfs_printf_directive *new_directive() { perror("dstralloc()"); goto error; } - directive->time_field = 0; + directive->stat_field = 0; directive->c = 0; directive->mtab = NULL; directive->next = NULL; @@ -591,7 +599,7 @@ struct bfs_printf *parse_bfs_printf(const char *format, struct cmdline *cmdline) switch (c) { case 'a': directive->fn = bfs_printf_ctime; - directive->time_field = ATIME; + directive->stat_field = BFS_STAT_ATIME; command->needs_stat = true; break; case 'b': @@ -600,7 +608,7 @@ struct bfs_printf *parse_bfs_printf(const char *format, struct cmdline *cmdline) break; case 'c': directive->fn = bfs_printf_ctime; - directive->time_field = CTIME; + directive->stat_field = BFS_STAT_CTIME; command->needs_stat = true; break; case 'd': @@ -681,7 +689,7 @@ struct bfs_printf *parse_bfs_printf(const char *format, struct cmdline *cmdline) break; case 't': directive->fn = bfs_printf_ctime; - directive->time_field = MTIME; + directive->stat_field = BFS_STAT_MTIME; command->needs_stat = true; break; case 'u': @@ -700,13 +708,13 @@ struct bfs_printf *parse_bfs_printf(const char *format, struct cmdline *cmdline) break; case 'A': - directive->time_field = ATIME; + directive->stat_field = BFS_STAT_ATIME; goto directive_strftime; case 'C': - directive->time_field = CTIME; + directive->stat_field = BFS_STAT_CTIME; goto directive_strftime; case 'T': - directive->time_field = MTIME; + directive->stat_field = BFS_STAT_MTIME; goto directive_strftime; directive_strftime: -- cgit v1.2.3