summaryrefslogtreecommitdiff
path: root/src/statx.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/statx.c')
-rw-r--r--src/statx.c120
1 files changed, 120 insertions, 0 deletions
diff --git a/src/statx.c b/src/statx.c
new file mode 100644
index 000000000..4973b0a63
--- /dev/null
+++ b/src/statx.c
@@ -0,0 +1,120 @@
+/*
+ * Copyright (c) 2017-2020 The strace developers.
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ */
+
+#include "defs.h"
+#include "statx.h"
+
+#include <sys/stat.h>
+
+#include "xlat/statx_masks.h"
+#include "xlat/statx_attrs.h"
+#include "xlat/at_statx_sync_types.h"
+
+static void
+print_statx_timestamp(const struct_statx_timestamp *const p)
+{
+ tprint_struct_begin();
+ PRINT_FIELD_D(*p, tv_sec);
+ tprint_struct_next();
+ PRINT_FIELD_U(*p, tv_nsec);
+ tprint_struct_end();
+ tprints_comment(sprinttime_nsec(p->tv_sec,
+ zero_extend_signed_to_ull(p->tv_nsec)));
+}
+
+SYS_FUNC(statx)
+{
+ if (entering(tcp)) {
+ print_dirfd(tcp, tcp->u_arg[0]);
+ tprints(", ");
+ printpath(tcp, tcp->u_arg[1]);
+ tprints(", ");
+
+ unsigned int flags = tcp->u_arg[2];
+ printflags(at_statx_sync_types, flags & AT_STATX_SYNC_TYPE,
+ NULL);
+ flags &= ~AT_STATX_SYNC_TYPE;
+ if (flags) {
+ tprints("|");
+ printflags(at_flags, flags, NULL);
+ }
+
+ tprints(", ");
+ printflags(statx_masks, tcp->u_arg[3], "STATX_???");
+ tprints(", ");
+ } else {
+ struct_statx stx;
+ if (umove_or_printaddr(tcp, tcp->u_arg[4], &stx))
+ return 0;
+
+ tprint_struct_begin();
+ PRINT_FIELD_FLAGS(stx, stx_mask, statx_masks,
+ "STATX_???");
+
+ if (!abbrev(tcp)) {
+ tprint_struct_next();
+ PRINT_FIELD_U(stx, stx_blksize);
+ }
+
+ tprint_struct_next();
+ PRINT_FIELD_FLAGS(stx, stx_attributes, statx_attrs,
+ "STATX_ATTR_???");
+
+ if (!abbrev(tcp)) {
+ tprint_struct_next();
+ PRINT_FIELD_U(stx, stx_nlink);
+ tprint_struct_next();
+ PRINT_FIELD_ID(stx, stx_uid);
+ tprint_struct_next();
+ PRINT_FIELD_ID(stx, stx_gid);
+ }
+
+ tprint_struct_next();
+ PRINT_FIELD_OBJ_VAL(stx, stx_mode, print_symbolic_mode_t);
+
+ if (!abbrev(tcp)) {
+ tprint_struct_next();
+ PRINT_FIELD_U(stx, stx_ino);
+ }
+
+ tprint_struct_next();
+ PRINT_FIELD_U(stx, stx_size);
+
+ if (!abbrev(tcp)) {
+ tprint_struct_next();
+ PRINT_FIELD_U(stx, stx_blocks);
+ tprint_struct_next();
+ PRINT_FIELD_FLAGS(stx, stx_attributes_mask,
+ statx_attrs, "STATX_ATTR_???");
+ tprint_struct_next();
+ PRINT_FIELD_OBJ_PTR(stx, stx_atime,
+ print_statx_timestamp);
+ tprint_struct_next();
+ PRINT_FIELD_OBJ_PTR(stx, stx_btime,
+ print_statx_timestamp);
+ tprint_struct_next();
+ PRINT_FIELD_OBJ_PTR(stx, stx_ctime,
+ print_statx_timestamp);
+ tprint_struct_next();
+ PRINT_FIELD_OBJ_PTR(stx, stx_mtime,
+ print_statx_timestamp);
+ tprint_struct_next();
+ PRINT_FIELD_U(stx, stx_rdev_major);
+ tprint_struct_next();
+ PRINT_FIELD_U(stx, stx_rdev_minor);
+ tprint_struct_next();
+ PRINT_FIELD_U(stx, stx_dev_major);
+ tprint_struct_next();
+ PRINT_FIELD_U(stx, stx_dev_minor);
+ } else {
+ tprint_struct_next();
+ tprint_more_data_follows();
+ }
+ tprint_struct_end();
+ }
+ return 0;
+}