[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH] stat: fallback if statx() is not available
From: |
Ville Heikkinen |
Subject: |
[PATCH] stat: fallback if statx() is not available |
Date: |
Tue, 8 Sep 2020 10:56:51 +0300 |
In case statx() returns EPERM or ENOSYS, fallback to use fstat(),
lstat() and stat() instead.
It's possible that the statx() is not functional e.g. due to the
used seccomp filters. Because of that, it would be good to fallback
to use the other methods to retrieve the stat info.
---
src/stat.c | 37 +++++++++++++++++++++++++++++--------
1 file changed, 29 insertions(+), 8 deletions(-)
diff --git a/src/stat.c b/src/stat.c
index 4e6c2aa86..f53f98c3d 100644
--- a/src/stat.c
+++ b/src/stat.c
@@ -246,6 +246,10 @@ static char const *trailing_delim = "";
static char const *decimal_point;
static size_t decimal_point_len;
+#if USE_STATX
+static bool use_stat = false;
+#endif
+
static bool
print_stat (char *pformat, size_t prefix_len, unsigned int m,
int fd, char const *filename, void const *data);
@@ -1329,9 +1333,13 @@ format_to_mask (char const *format)
return mask;
}
+static bool ATTRIBUTE_WARN_UNUSED_RESULT
+do_stat (char const *filename, char const *format,
+ char const *format2);
+
/* 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)
+do_statx (char const *filename, char const *format, char const *format2)
{
int fd = STREQ (filename, "-") ? 0 : AT_FDCWD;
int flags = 0;
@@ -1360,6 +1368,11 @@ do_stat (char const *filename, char const *format, char
const *format2)
fd = statx (fd, pathname, flags, format_to_mask (format), &stx);
if (fd < 0)
{
+ if (errno == EPERM || errno == ENOSYS)
+ {
+ use_stat = true;
+ return do_stat (filename, format, format2);
+ }
if (flags & AT_EMPTY_PATH)
error (0, errno, _("cannot stat standard input"));
else
@@ -1378,7 +1391,7 @@ do_stat (char const *filename, char const *format, char
const *format2)
return ! fail;
}
-#else /* USE_STATX */
+#endif /* USE_STATX */
static struct timespec
get_birthtime (int fd, char const *filename, struct stat const *st)
@@ -1449,7 +1462,6 @@ do_stat (char const *filename, char const *format,
bool fail = print_it (format, fd, filename, print_stat, &pa);
return ! fail;
}
-#endif /* USE_STATX */
/* Print stat info. Return zero upon success, nonzero upon failure. */
@@ -1548,9 +1560,10 @@ print_stat (char *pformat, size_t prefix_len, unsigned
int m,
break;
case 'w':
{
-#if ! USE_STATX
- btime = get_birthtime (fd, filename, statbuf);
+#if USE_STATX
+ if (use_stat)
#endif
+ btime = get_birthtime (fd, filename, statbuf);
if (btime.tv_nsec < 0)
out_string (pformat, prefix_len, "-");
else
@@ -1559,9 +1572,10 @@ print_stat (char *pformat, size_t prefix_len, unsigned
int m,
break;
case 'W':
{
-#if ! USE_STATX
- btime = get_birthtime (fd, filename, statbuf);
+#if USE_STATX
+ if (use_stat)
#endif
+ btime = get_birthtime (fd, filename, statbuf);
out_epoch_sec (pformat, prefix_len, neg_to_zero (btime));
}
break;
@@ -1903,7 +1917,14 @@ main (int argc, char *argv[])
for (int i = optind; i < argc; i++)
ok &= (fs
? do_statfs (argv[i], format)
- : do_stat (argv[i], format, format2));
+#if USE_STATX
+ : (use_stat
+ ? do_stat (argv[i], format, format2)
+ : do_statx (argv[i], format, format2))
+#else
+ : do_stat (argv[i], format, format2)
+#endif
+ );
return ok ? EXIT_SUCCESS : EXIT_FAILURE;
}
--
2.26.2
- [PATCH] stat: fallback if statx() is not available,
Ville Heikkinen <=