[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH 3/3] ls: add statx-enabled variants of stat and lstat calls
From: |
Jeff Layton |
Subject: |
[PATCH 3/3] ls: add statx-enabled variants of stat and lstat calls |
Date: |
Wed, 11 Sep 2019 09:51:45 -0400 |
* add wrapper functions for stat, lstat and stat_for_mode so that we
can conditionally plug in statx-enabled variants
* add statx-enabled functions and set the request mask based on the
output format and what values are needed
---
src/ls.c | 73 ++++++++++++++++++++++++++++++++++++++++++++++++++++----
1 file changed, 69 insertions(+), 4 deletions(-)
diff --git a/src/ls.c b/src/ls.c
index 8e5015e5ac12..3c12f63e595b 100644
--- a/src/ls.c
+++ b/src/ls.c
@@ -3166,6 +3166,71 @@ needs_quoting (char const* name)
return *name != *test || strlen (name) != len;
}
+#if USE_STATX
+static unsigned int
+calc_request_mask(void)
+{
+ unsigned int mask = STATX_MODE;
+
+ if (print_inode)
+ mask |= STATX_INO;
+ if (format == long_format) {
+ mask |= STATX_NLINK | STATX_SIZE;
+ if (print_owner || print_author)
+ mask |= STATX_UID;
+ if (print_group)
+ mask |= STATX_GID;
+ }
+ return mask;
+}
+
+static int
+do_statx (const char *name, struct stat *st, int flags, unsigned int mask)
+{
+ struct statx stx;
+ int ret = statx(AT_FDCWD, name, flags, mask, &stx);
+ if (ret >= 0)
+ statx_to_stat(&stx, st);
+ return ret;
+}
+
+static inline int
+do_stat(const char *name, struct stat *st)
+{
+ return do_statx(name, st, 0, calc_request_mask());
+}
+
+static int
+do_lstat (const char *name, struct stat *st)
+{
+ return do_statx(name, st, AT_SYMLINK_NOFOLLOW, calc_request_mask());
+}
+
+static int
+stat_for_mode(const char *name, struct stat *st)
+{
+ return do_statx(name, st, 0, STATX_MODE);
+}
+#else
+static inline int
+do_stat (const char *name, struct stat *st)
+{
+ return stat(name, st);
+}
+
+static inline int
+do_lstat (const char *name, struct stat *st)
+{
+ return lstat(name, st);
+}
+
+static int
+stat_for_mode(const char *name, struct stat *st)
+{
+ return do_stat(name, st);
+}
+#endif
+
/* Add a file to the current table of files.
Verify that the file exists, and print an error message if it does not.
Return the number of blocks that the file occupies. */
@@ -3264,7 +3329,7 @@ gobble_file (char const *name, enum filetype type, ino_t
inode,
switch (dereference)
{
case DEREF_ALWAYS:
- err = stat (full_name, &f->stat);
+ err = do_stat (full_name, &f->stat);
do_deref = true;
break;
@@ -3273,7 +3338,7 @@ gobble_file (char const *name, enum filetype type, ino_t
inode,
if (command_line_arg)
{
bool need_lstat;
- err = stat (full_name, &f->stat);
+ err = do_stat (full_name, &f->stat);
do_deref = true;
if (dereference == DEREF_COMMAND_LINE_ARGUMENTS)
@@ -3293,7 +3358,7 @@ gobble_file (char const *name, enum filetype type, ino_t
inode,
FALLTHROUGH;
default: /* DEREF_NEVER */
- err = lstat (full_name, &f->stat);
+ err = do_lstat (full_name, &f->stat);
do_deref = false;
break;
}
@@ -3382,7 +3447,7 @@ gobble_file (char const *name, enum filetype type, ino_t
inode,
they won't be traced and when no indicator is needed. */
if (linkname
&& (file_type <= indicator_style || check_symlink_mode)
- && stat (linkname, &linkstats) == 0)
+ && stat_for_mode(linkname, &linkstats) == 0)
{
f->linkok = true;
f->linkmode = linkstats.st_mode;
--
2.21.0
[PATCH 3/3] ls: add statx-enabled variants of stat and lstat calls,
Jeff Layton <=