1 /*
2 * Copyright (c) 2017-2022 The strace developers.
3 * All rights reserved.
4 *
5 * SPDX-License-Identifier: LGPL-2.1-or-later
6 */
7
8 #include "defs.h"
9 #include "statx.h"
10
11 #include <sys/stat.h>
12 #include <linux/fcntl.h>
13
14 #include "xlat/statx_masks.h"
15 #include "xlat/statx_attrs.h"
16 #include "xlat/at_statx_sync_types.h"
17
18 static void
19 print_statx_timestamp(const struct_statx_timestamp *const p)
20 {
21 tprint_struct_begin();
22 PRINT_FIELD_D(*p, tv_sec);
23 tprint_struct_next();
24 PRINT_FIELD_U(*p, tv_nsec);
25 tprint_struct_end();
26 tprints_comment(sprinttime_nsec(p->tv_sec,
27 zero_extend_signed_to_ull(p->tv_nsec)));
28 }
29
30 SYS_FUNC(statx)
31 {
32 if (entering(tcp)) {
33 /* dirfd */
34 print_dirfd(tcp, tcp->u_arg[0]);
35 tprint_arg_next();
36
37 /* pathname */
38 printpath(tcp, tcp->u_arg[1]);
39 tprint_arg_next();
40
41 /* flags */
42 unsigned int flags = tcp->u_arg[2];
43 tprint_flags_begin();
44 printflags_in(at_statx_sync_types, flags & AT_STATX_SYNC_TYPE,
45 NULL);
46 flags &= ~AT_STATX_SYNC_TYPE;
47 if (flags) {
48 tprint_flags_or();
49 printflags_in(at_flags, flags, NULL);
50 }
51 tprint_flags_end();
52 tprint_arg_next();
53
54 /* mask */
55 printflags(statx_masks, tcp->u_arg[3], "STATX_???");
56 tprint_arg_next();
57 } else {
58 /* statxbuf */
59 struct_statx stx;
60 if (umove_or_printaddr(tcp, tcp->u_arg[4], &stx))
61 return 0;
62
63 tprint_struct_begin();
64 PRINT_FIELD_FLAGS(stx, stx_mask, statx_masks,
65 "STATX_???");
66
67 if (!abbrev(tcp)) {
68 tprint_struct_next();
69 PRINT_FIELD_U(stx, stx_blksize);
70 }
71
72 tprint_struct_next();
73 PRINT_FIELD_FLAGS(stx, stx_attributes, statx_attrs,
74 "STATX_ATTR_???");
75
76 if (!abbrev(tcp)) {
77 if (stx.stx_mask & STATX_NLINK) {
78 tprint_struct_next();
79 PRINT_FIELD_U(stx, stx_nlink);
80 }
81 if (stx.stx_mask & STATX_UID) {
82 tprint_struct_next();
83 PRINT_FIELD_ID(stx, stx_uid);
84 }
85 if (stx.stx_mask & STATX_GID) {
86 tprint_struct_next();
87 PRINT_FIELD_ID(stx, stx_gid);
88 }
89 }
90
91 if (stx.stx_mask & (STATX_TYPE|STATX_MODE)) {
92 tprint_struct_next();
93 PRINT_FIELD_OBJ_VAL(stx, stx_mode,
94 print_symbolic_mode_t);
95 }
96
97 if (!abbrev(tcp)) {
98 if (stx.stx_mask & STATX_INO) {
99 tprint_struct_next();
100 PRINT_FIELD_U(stx, stx_ino);
101 }
102 }
103
104 if (stx.stx_mask & STATX_SIZE) {
105 tprint_struct_next();
106 PRINT_FIELD_U(stx, stx_size);
107 }
108
109 if (!abbrev(tcp)) {
110 if (stx.stx_mask & STATX_BLOCKS) {
111 tprint_struct_next();
112 PRINT_FIELD_U(stx, stx_blocks);
113 }
114 tprint_struct_next();
115 PRINT_FIELD_FLAGS(stx, stx_attributes_mask,
116 statx_attrs, "STATX_ATTR_???");
117 if (stx.stx_mask & STATX_ATIME) {
118 tprint_struct_next();
119 PRINT_FIELD_OBJ_PTR(stx, stx_atime,
120 print_statx_timestamp);
121 }
122 if (stx.stx_mask & STATX_BTIME) {
123 tprint_struct_next();
124 PRINT_FIELD_OBJ_PTR(stx, stx_btime,
125 print_statx_timestamp);
126 }
127 if (stx.stx_mask & STATX_CTIME) {
128 tprint_struct_next();
129 PRINT_FIELD_OBJ_PTR(stx, stx_ctime,
130 print_statx_timestamp);
131 }
132 if (stx.stx_mask & STATX_MTIME) {
133 tprint_struct_next();
134 PRINT_FIELD_OBJ_PTR(stx, stx_mtime,
135 print_statx_timestamp);
136 }
137 tprint_struct_next();
138 PRINT_FIELD_U(stx, stx_rdev_major);
139 tprint_struct_next();
140 PRINT_FIELD_U(stx, stx_rdev_minor);
141 tprint_struct_next();
142 PRINT_FIELD_U(stx, stx_dev_major);
143 tprint_struct_next();
144 PRINT_FIELD_U(stx, stx_dev_minor);
145 if (stx.stx_mask & STATX_MNT_ID) {
146 tprint_struct_next();
147 PRINT_FIELD_X(stx, stx_mnt_id);
148 }
149 if (stx.stx_mask & STATX_DIOALIGN) {
150 tprint_struct_next();
151 PRINT_FIELD_U(stx, stx_dio_mem_align);
152 tprint_struct_next();
153 PRINT_FIELD_U(stx, stx_dio_offset_align);
154 }
155 } else {
156 tprint_struct_next();
157 tprint_more_data_follows();
158 }
159 tprint_struct_end();
160 }
161 return 0;
162 }