summaryrefslogtreecommitdiffstats
path: root/printf.c
diff options
context:
space:
mode:
authorTavian Barnes <tavianator@tavianator.com>2018-01-08 21:43:23 -0500
committerTavian Barnes <tavianator@tavianator.com>2018-01-08 21:52:50 -0500
commit50432108fb3ef826301626b94c5e82ad2ab2bd75 (patch)
treeed8946e5ab8bac5adda495e9c8ca67a8ac99fd19 /printf.c
parent7d68aac4a50ab4d4881832bc7de568c2b5d4ea8b (diff)
downloadbfs-50432108fb3ef826301626b94c5e82ad2ab2bd75.tar.xz
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.
Diffstat (limited to 'printf.c')
-rw-r--r--printf.c92
1 files changed, 50 insertions, 42 deletions
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 <assert.h>
#include <errno.h>
@@ -29,7 +30,6 @@
#include <stdint.h>
#include <stdio.h>
#include <string.h>
-#include <sys/stat.h>
#include <time.h>
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: