[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH v3 3/4] stat: only set STATX_* mask bits for things we want to pr
From: |
Jeff Layton |
Subject: |
[PATCH v3 3/4] stat: only set STATX_* mask bits for things we want to print |
Date: |
Tue, 16 Apr 2019 17:22:42 -0400 |
Scan the format string to build a STATX_* mask prior to calling statx.
This allows us to avoid setting bits for attributes that we don't
intend to display, which can mean a much lighter-weight operation on
some filesystems.
* src/stat.c: only set STATX_* mask bits for things we want to print
---
src/stat.c | 81 ++++++++++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 79 insertions(+), 2 deletions(-)
diff --git a/src/stat.c b/src/stat.c
index 264e9138cdc9..2bbc75792b5a 100644
--- a/src/stat.c
+++ b/src/stat.c
@@ -1370,6 +1370,84 @@ print_statx (char *pformat, size_t prefix_len, unsigned
int m,
return fail;
}
+static unsigned int
+fmt_to_mask(char fmt)
+{
+ switch(fmt)
+ {
+ case 'N':
+ return STATX_MODE|STATX_SIZE;
+ case 'd':
+ case 'D':
+ return STATX_MODE;
+ case 'i':
+ return STATX_INO;
+ case 'a':
+ case 'A':
+ return STATX_MODE;
+ case 'f':
+ return STATX_MODE|STATX_TYPE;
+ case 'F':
+ return STATX_TYPE;
+ case 'h':
+ return STATX_NLINK;
+ case 'u':
+ case 'U':
+ return STATX_UID;
+ case 'g':
+ case 'G':
+ return STATX_GID;
+ case 'm':
+ return STATX_MODE|STATX_INO;
+ case 's':
+ return STATX_SIZE;
+ case 't':
+ case 'T':
+ return STATX_MODE;
+ case 'b':
+ return STATX_BLOCKS;
+ case 'w':
+ case 'W':
+ return STATX_BTIME;
+ case 'x':
+ case 'X':
+ return STATX_ATIME;
+ case 'y':
+ case 'Y':
+ return STATX_MTIME;
+ case 'z':
+ case 'Z':
+ return STATX_CTIME;
+ }
+ return 0;
+}
+
+static unsigned int __attribute__((const))
+format_to_mask(char const *format)
+{
+ unsigned int mask = 0;
+ char const *b;
+
+ for (b = format; *b; b++)
+ {
+ if (*b != '%')
+ continue;
+
+ size_t len = strspn (b + 1, printf_flags);
+ char const *fmt_char = b + len + 1;
+ fmt_char += strspn (fmt_char, digits);
+ if (*fmt_char == '.')
+ fmt_char += 1 + strspn (fmt_char + 1, digits);
+ char fmt_code = *fmt_char;
+
+ b = fmt_char;
+ if (fmt_code == '\0')
+ break;
+ mask |= fmt_to_mask(fmt_code);
+ }
+ return mask;
+}
+
/* statx the file and print what we find */
static bool ATTRIBUTE_WARN_UNUSED_RESULT
do_stat (char const *filename, char const *format, char const *format2)
@@ -1394,8 +1472,7 @@ do_stat (char const *filename, char const *format, char
const *format2)
flags = AT_SYMLINK_NOFOLLOW;
}
- /* FIXME: set request mask based on format */
- fd = statx(fd, pathname, flags, STATX_BASIC_STATS|STATX_BTIME, &stx);
+ fd = statx(fd, pathname, flags, format_to_mask(format), &stx);
if (fd < 0)
{
if (flags & AT_EMPTY_PATH)
--
2.20.1