[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH 4/4] stat: remove print_statx() and reuse print_stat()
From: |
Pádraig Brady |
Subject: |
[PATCH 4/4] stat: remove print_statx() and reuse print_stat() |
Date: |
Mon, 3 Jun 2019 03:55:52 +0100 |
* src/stat.c: Pass the btime into print_stat()
and reuse this function to print the (already transformed)
statx attributes.
---
src/stat.c | 279 ++++++++++++++++++-------------------------------------------
1 file changed, 82 insertions(+), 197 deletions(-)
diff --git a/src/stat.c b/src/stat.c
index 3e8f531..492daf3 100644
--- a/src/stat.c
+++ b/src/stat.c
@@ -243,6 +243,10 @@ static char const *trailing_delim = "";
static char const *decimal_point;
static size_t decimal_point_len;
+static bool
+print_stat (char *pformat, size_t prefix_len, unsigned int m,
+ int fd, char const *filename, void const *data);
+
/* Return the type of the specified file system.
Some systems have statfvs.f_basetype[FSTYPSZ] (AIX, HP-UX, and Solaris).
Others have statvfs.f_fstypename[_VFS_NAMELEN] (NetBSD 3.0).
@@ -1227,6 +1231,11 @@ do_statfs (char const *filename, char const *format)
return ! fail;
}
+struct print_args {
+ struct stat *st;
+ struct timespec btime;
+};
+
#if HAVE_STATX && defined STATX_INO
/* Ask statx to avoid syncing? */
static bool dont_sync;
@@ -1234,11 +1243,6 @@ static bool dont_sync;
/* Ask statx to force sync? */
static bool force_sync;
-struct printarg {
- struct statx *stx;
- struct stat *st;
-};
-
/* Much of the format printing requires a struct stat or timespec */
static struct timespec
statx_timestamp_to_timespec (struct statx_timestamp tsx)
@@ -1259,151 +1263,17 @@ statx_to_stat (struct statx *stx, struct stat *stat)
stat->st_nlink = stx->stx_nlink;
stat->st_uid = stx->stx_uid;
stat->st_gid = stx->stx_gid;
- stat->st_dev = makedev (stx->stx_rdev_major, stx->stx_rdev_minor);
+ stat->st_rdev = makedev (stx->stx_rdev_major, stx->stx_rdev_minor);
stat->st_size = stx->stx_size;
stat->st_blksize = stx->stx_blksize;
- /* Skip setting st_blocks to avoid sc_prohibit_stat_st_blocks warning */
+/* define to avoid sc_prohibit_stat_st_blocks. */
+# define SC_ST_BLOCKS st_blocks
+ stat->SC_ST_BLOCKS = stx->stx_blocks;
stat->st_atim = statx_timestamp_to_timespec (stx->stx_atime);
stat->st_mtim = statx_timestamp_to_timespec (stx->stx_mtime);
stat->st_ctim = statx_timestamp_to_timespec (stx->stx_ctime);
}
-/* Print statx info. Return zero upon success, nonzero upon failure. */
-static bool
-print_statx (char *pformat, size_t prefix_len, unsigned int m,
- int fd, char const *filename, void const *data)
-{
- struct printarg *parg = (struct printarg *) data;
- struct statx *stx = parg->stx;
- struct stat *st = parg->st;
- struct passwd *pw_ent;
- struct group *gw_ent;
- bool fail = false;
-
- switch (m)
- {
- case 'n':
- out_string (pformat, prefix_len, filename);
- break;
- case 'N':
- out_string (pformat, prefix_len, quoteN (filename));
- if (S_ISLNK (stx->stx_mode))
- {
- char *linkname = areadlink_with_size (filename, stx->stx_size);
- if (linkname == NULL)
- {
- error (0, errno, _("cannot read symbolic link %s"),
- quoteaf (filename));
- return true;
- }
- printf (" -> ");
- out_string (pformat, prefix_len, quoteN (linkname));
- free (linkname);
- }
- break;
- case 'd':
- out_uint (pformat, prefix_len, st->st_dev);
- break;
- case 'D':
- out_uint_x (pformat, prefix_len, st->st_dev);
- break;
- case 'i':
- out_uint (pformat, prefix_len, stx->stx_ino);
- break;
- case 'a':
- out_uint_o (pformat, prefix_len, stx->stx_mode & CHMOD_MODE_BITS);
- break;
- case 'A':
- out_string (pformat, prefix_len, human_access (st));
- break;
- case 'f':
- out_uint_x (pformat, prefix_len, stx->stx_mode);
- break;
- case 'F':
- out_string (pformat, prefix_len, file_type (st));
- break;
- case 'h':
- out_uint (pformat, prefix_len, stx->stx_nlink);
- break;
- case 'u':
- out_uint (pformat, prefix_len, stx->stx_uid);
- break;
- case 'U':
- pw_ent = getpwuid (stx->stx_uid);
- out_string (pformat, prefix_len,
- pw_ent ? pw_ent->pw_name : "UNKNOWN");
- break;
- case 'g':
- out_uint (pformat, prefix_len, stx->stx_gid);
- break;
- case 'G':
- gw_ent = getgrgid (stx->stx_gid);
- out_string (pformat, prefix_len,
- gw_ent ? gw_ent->gr_name : "UNKNOWN");
- break;
- case 'm':
- fail |= out_mount_point (filename, pformat, prefix_len, st);
- break;
- case 's':
- out_int (pformat, prefix_len, stx->stx_size);
- break;
- case 't':
- out_uint_x (pformat, prefix_len, stx->stx_rdev_major);
- break;
- case 'T':
- out_uint_x (pformat, prefix_len, stx->stx_rdev_minor);
- break;
- case 'B':
- out_uint (pformat, prefix_len, ST_NBLOCKSIZE);
- break;
- case 'b':
- out_uint (pformat, prefix_len, stx->stx_blocks);
- break;
- case 'o':
- out_uint (pformat, prefix_len, stx->stx_blksize);
- break;
- case 'w':
- if (stx->stx_mask & STATX_BTIME)
- out_string (pformat, prefix_len,
- human_time (statx_timestamp_to_timespec (stx->stx_btime)));
- else
- out_string (pformat, prefix_len, "-");
- break;
- case 'W':
- if (stx->stx_mask & STATX_BTIME)
- out_epoch_sec (pformat, prefix_len,
- statx_timestamp_to_timespec (stx->stx_btime));
- else
- out_string (pformat, prefix_len, "0");
- break;
- case 'x':
- out_string (pformat, prefix_len, human_time (st->st_atim));
- break;
- case 'X':
- out_epoch_sec (pformat, prefix_len, st->st_atim);
- break;
- case 'y':
- out_string (pformat, prefix_len, human_time (st->st_mtim));
- break;
- case 'Y':
- out_epoch_sec (pformat, prefix_len, st->st_mtim);
- break;
- case 'z':
- out_string (pformat, prefix_len, human_time (st->st_ctim));
- break;
- case 'Z':
- out_epoch_sec (pformat, prefix_len, st->st_ctim);
- break;
- case 'C':
- fail |= out_file_context (pformat, prefix_len, filename);
- break;
- default:
- fputc ('?', stdout);
- break;
- }
- return fail;
-}
-
static unsigned int
fmt_to_mask (char fmt)
{
@@ -1484,10 +1354,9 @@ do_stat (char const *filename, char const *format, char
const *format2)
struct stat st;
struct statx stx;
const char *pathname = filename;
- struct printarg pa = {
- .stx = &stx,
- .st = &st
- };
+ struct print_args pa;
+ pa.st = &st;
+ pa.btime = (struct timespec) {-1, -1};
if (AT_FDCWD != fd)
{
@@ -1510,20 +1379,23 @@ do_stat (char const *filename, char const *format, char
const *format2)
if (flags & AT_EMPTY_PATH)
error (0, errno, _("cannot stat standard input"));
else
-error (0, errno, _("cannot statx %s"), quoteaf (filename));
+ error (0, errno, _("cannot statx %s"), quoteaf (filename));
return false;
}
if (S_ISBLK (stx.stx_mode) || S_ISCHR (stx.stx_mode))
format = format2;
- /* Many of the gnulib routines require a struct stat */
statx_to_stat (&stx, &st);
+ if (stx.stx_mask & STATX_BTIME)
+ pa.btime = statx_timestamp_to_timespec (stx.stx_btime);
- bool fail = print_it (format, fd, filename, print_statx, &pa);
+ bool fail = print_it (format, fd, filename, print_stat, &pa);
return ! fail;
}
+
#else /* HAVE_STATX && defined STATX_INO */
+
static struct timespec
get_birthtime (int fd, char const *filename, struct stat const *st)
{
@@ -1556,12 +1428,54 @@ get_birthtime (int fd, char const *filename, struct
stat const *st)
return ts;
}
+
+/* stat the file and print what we find */
+static bool ATTRIBUTE_WARN_UNUSED_RESULT
+do_stat (char const *filename, char const *format,
+ char const *format2)
+{
+ int fd = STREQ (filename, "-") ? 0 : -1;
+ struct stat statbuf;
+ struct print_args pa;
+ pa.st = &statbuf;
+ pa.btime = (struct timespec) {-1, -1};
+
+ if (0 <= fd)
+ {
+ if (fstat (fd, &statbuf) != 0)
+ {
+ error (0, errno, _("cannot stat standard input"));
+ return false;
+ }
+ }
+ /* We can't use the shorter
+ (follow_links?stat:lstat) (filename, &statbug)
+ since stat might be a function-like macro. */
+ else if ((follow_links
+ ? stat (filename, &statbuf)
+ : lstat (filename, &statbuf)) != 0)
+ {
+ error (0, errno, _("cannot stat %s"), quoteaf (filename));
+ return false;
+ }
+
+ if (S_ISBLK (statbuf.st_mode) || S_ISCHR (statbuf.st_mode))
+ format = format2;
+
+ bool fail = print_it (format, fd, filename, print_stat, &pa);
+ return ! fail;
+}
+#endif /* HAVE_STATX && defined STATX_INO */
+
+
/* Print stat info. Return zero upon success, nonzero upon failure. */
static bool
print_stat (char *pformat, size_t prefix_len, unsigned int m,
int fd, char const *filename, void const *data)
{
- struct stat *statbuf = (struct stat *) data;
+ struct print_args *parg = (struct print_args *) data;
+ struct stat *statbuf = parg->st;
+ struct timespec btime = parg->btime;
struct passwd *pw_ent;
struct group *gw_ent;
bool fail = false;
@@ -1627,18 +1541,18 @@ print_stat (char *pformat, size_t prefix_len, unsigned
int m,
out_string (pformat, prefix_len,
gw_ent ? gw_ent->gr_name : "UNKNOWN");
break;
- case 't':
- out_uint_x (pformat, prefix_len, major (statbuf->st_rdev));
- break;
case 'm':
fail |= out_mount_point (filename, pformat, prefix_len, statbuf);
break;
- case 'T':
- out_uint_x (pformat, prefix_len, minor (statbuf->st_rdev));
- break;
case 's':
out_int (pformat, prefix_len, statbuf->st_size);
break;
+ case 't':
+ out_uint_x (pformat, prefix_len, major (statbuf->st_rdev));
+ break;
+ case 'T':
+ out_uint_x (pformat, prefix_len, minor (statbuf->st_rdev));
+ break;
case 'B':
out_uint (pformat, prefix_len, ST_NBLOCKSIZE);
break;
@@ -1650,16 +1564,22 @@ print_stat (char *pformat, size_t prefix_len, unsigned
int m,
break;
case 'w':
{
- struct timespec t = get_birthtime (fd, filename, statbuf);
- if (t.tv_nsec < 0)
+#if ! defined HAVE_STATX || ! defined STATX_INO
+ btime = get_birthtime (fd, filename, statbuf);
+#endif
+ if (btime.tv_nsec < 0)
out_string (pformat, prefix_len, "-");
else
- out_string (pformat, prefix_len, human_time (t));
+ out_string (pformat, prefix_len, human_time (btime));
}
break;
case 'W':
- out_epoch_sec (pformat, prefix_len,
- neg_to_zero (get_birthtime (fd, filename, statbuf)));
+ {
+#if ! defined HAVE_STATX || ! defined STATX_INO
+ btime = get_birthtime (fd, filename, statbuf);
+#endif
+ out_epoch_sec (pformat, prefix_len, neg_to_zero (btime));
+ }
break;
case 'x':
out_string (pformat, prefix_len, human_time (get_stat_atime (statbuf)));
@@ -1689,41 +1609,6 @@ print_stat (char *pformat, size_t prefix_len, unsigned
int m,
return fail;
}
-/* stat the file and print what we find */
-static bool ATTRIBUTE_WARN_UNUSED_RESULT
-do_stat (char const *filename, char const *format,
- char const *format2)
-{
- int fd = STREQ (filename, "-") ? 0 : -1;
- struct stat statbuf;
-
- if (0 <= fd)
- {
- if (fstat (fd, &statbuf) != 0)
- {
- error (0, errno, _("cannot stat standard input"));
- return false;
- }
- }
- /* We can't use the shorter
- (follow_links?stat:lstat) (filename, &statbug)
- since stat might be a function-like macro. */
- else if ((follow_links
- ? stat (filename, &statbuf)
- : lstat (filename, &statbuf)) != 0)
- {
- error (0, errno, _("cannot stat %s"), quoteaf (filename));
- return false;
- }
-
- if (S_ISBLK (statbuf.st_mode) || S_ISCHR (statbuf.st_mode))
- format = format2;
-
- bool fail = print_it (format, fd, filename, print_stat, &statbuf);
- return ! fail;
-}
-#endif /* HAVE_STATX && defined STATX_INO */
-
/* Return an allocated format string in static storage that
corresponds to whether FS and TERSE options were declared. */
static char *
--
2.9.3