blob: 30c2c239b9c20adaca2cb0aa2e6093becfea9d49 [file] [log] [blame]
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001/*
2 * Copyright (c) 1991, 1992 Paul Kranenburg <pk@cs.few.eur.nl>
3 * Copyright (c) 1993 Branko Lankester <branko@hacktic.nl>
4 * Copyright (c) 1993, 1994, 1995, 1996 Rick Sladkey <jrs@world.std.com>
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00005 * Copyright (c) 1996-1999 Wichert Akkerman <wichert@cistron.nl>
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00006 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. The name of the author may not be used to endorse or promote products
17 * derived from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000029 */
30
31#include "defs.h"
Roland McGrathc531e572008-08-01 01:13:10 +000032
Dmitry V. Levinf19836b2014-12-30 11:18:47 +000033#undef dev_t
34#undef ino_t
35#undef mode_t
36#undef nlink_t
37#undef uid_t
38#undef gid_t
39#undef off_t
40#undef loff_t
41#define dev_t __kernel_dev_t
42#define ino_t __kernel_ino_t
43#define mode_t __kernel_mode_t
44#define nlink_t __kernel_nlink_t
45#define uid_t __kernel_uid_t
46#define gid_t __kernel_gid_t
47#define off_t __kernel_off_t
48#define loff_t __kernel_loff_t
Wichert Akkermana6013701999-07-08 14:00:58 +000049
Dmitry V. Levinc31481f2015-12-04 14:37:02 +000050#include "asm_stat.h"
Wichert Akkermana6013701999-07-08 14:00:58 +000051
Dmitry V. Levinf19836b2014-12-30 11:18:47 +000052#undef dev_t
53#undef ino_t
54#undef mode_t
55#undef nlink_t
56#undef uid_t
57#undef gid_t
58#undef off_t
59#undef loff_t
60#define dev_t dev_t
61#define ino_t ino_t
62#define mode_t mode_t
63#define nlink_t nlink_t
64#define uid_t uid_t
65#define gid_t gid_t
66#define off_t off_t
67#define loff_t loff_t
Denys Vlasenko84703742012-02-25 02:38:52 +010068
Dmitry V. Levinf19836b2014-12-30 11:18:47 +000069/* for S_IFMT */
Denys Vlasenko84703742012-02-25 02:38:52 +010070#define stat libc_stat
71#define stat64 libc_stat64
72#include <sys/stat.h>
73#undef stat
74#undef stat64
Denys Vlasenkoa6d91de2012-03-16 12:02:22 +010075/* These might be macros. */
Denys Vlasenko84703742012-02-25 02:38:52 +010076#undef st_atime
77#undef st_mtime
78#undef st_ctime
Wichert Akkermand4d8e921999-04-18 23:30:29 +000079
Dmitry V. Levinf19836b2014-12-30 11:18:47 +000080#if defined MAJOR_IN_SYSMACROS
Denys Vlasenko84703742012-02-25 02:38:52 +010081# include <sys/sysmacros.h>
Dmitry V. Levinf19836b2014-12-30 11:18:47 +000082#elif defined MAJOR_IN_MKDEV
Denys Vlasenko84703742012-02-25 02:38:52 +010083# include <sys/mkdev.h>
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000084#endif
85
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000086/* several stats */
87
Dmitry V. Levin721de782015-01-08 02:59:04 +000088#include "printstat.h"
89
Dmitry V. Levin525eed32015-08-08 12:12:13 +000090/* all locally defined structures provide these fields */
Dmitry V. Levin525eed32015-08-08 12:12:13 +000091#undef HAVE_STRUCT_STAT_ST_MTIME_NSEC
92#define HAVE_STRUCT_STAT_ST_MTIME_NSEC 1
93
Dmitry V. Levinf19836b2014-12-30 11:18:47 +000094#undef STAT32_PERSONALITY
95#if SUPPORTED_PERSONALITIES > 1
Dmitry V. Levin09dee9a2016-08-09 09:50:13 +000096# include "stat32.h"
97#endif
Andreas Schwabd69fa492010-07-12 21:39:57 +020098
Dmitry V. Levinf19836b2014-12-30 11:18:47 +000099#ifdef STAT32_PERSONALITY
Dmitry V. Levin721de782015-01-08 02:59:04 +0000100# define DO_PRINTSTAT do_printstat32
Dmitry V. Levinf19836b2014-12-30 11:18:47 +0000101# define STRUCT_STAT struct stat32
Dmitry V. Levin721de782015-01-08 02:59:04 +0000102# include "printstat.h"
Dmitry V. Levinf19836b2014-12-30 11:18:47 +0000103#endif /* STAT32_PERSONALITY */
Andreas Schwabd69fa492010-07-12 21:39:57 +0200104
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000105static void
Denys Vlasenko1d632462009-04-14 12:51:00 +0000106printstat(struct tcb *tcp, long addr)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000107{
Wichert Akkerman328c5e71999-04-16 00:21:26 +0000108 struct stat statbuf;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000109
Dmitry V. Levinf19836b2014-12-30 11:18:47 +0000110#ifdef STAT32_PERSONALITY
111 if (current_personality == STAT32_PERSONALITY) {
Dmitry V. Levinb6d80ff2015-07-20 12:09:44 +0000112 struct stat32 statbuf;
113
114 if (!umove_or_printaddr(tcp, addr, &statbuf))
115 do_printstat32(tcp, &statbuf);
Dmitry V. Levinf19836b2014-12-30 11:18:47 +0000116 return;
117 }
118#endif
119
Dmitry V. Levinb6d80ff2015-07-20 12:09:44 +0000120 if (!umove_or_printaddr(tcp, addr, &statbuf))
121 do_printstat(tcp, &statbuf);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000122}
123
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000124SYS_FUNC(stat)
Dmitry V. Levinc6ee0ec2015-01-08 01:14:53 +0000125{
126 if (entering(tcp)) {
127 printpath(tcp, tcp->u_arg[0]);
128 tprints(", ");
129 } else {
130 printstat(tcp, tcp->u_arg[1]);
131 }
132 return 0;
133}
134
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000135SYS_FUNC(fstat)
Dmitry V. Levinc6ee0ec2015-01-08 01:14:53 +0000136{
137 if (entering(tcp)) {
138 printfd(tcp, tcp->u_arg[0]);
139 tprints(", ");
140 } else {
141 printstat(tcp, tcp->u_arg[1]);
142 }
143 return 0;
144}
145
Dmitry V. Levin7b9bc442015-01-08 04:06:06 +0000146#if defined STAT32_PERSONALITY && !defined HAVE_STRUCT_STAT64
Dmitry V. Levinf19836b2014-12-30 11:18:47 +0000147# if defined AARCH64 || defined X86_64 || defined X32
Roland McGrathe6d0f712007-08-07 01:22:49 +0000148/*
Dmitry V. Levin8d411082014-12-28 16:41:24 +0000149 * Linux x86_64 and x32 have unified `struct stat' but their i386 personality
150 * needs `struct stat64'.
151 * linux/arch/x86/include/uapi/asm/stat.h defines `struct stat64' only for i386.
Elliott Hughes391c0d82014-04-03 17:50:14 -0700152 *
153 * Similarly, aarch64 has a unified `struct stat' but its arm personality
Dmitry V. Levin8d411082014-12-28 16:41:24 +0000154 * needs `struct stat64' (unlike x86, it shouldn't be packed).
Roland McGrathe6d0f712007-08-07 01:22:49 +0000155 */
156struct stat64 {
157 unsigned long long st_dev;
158 unsigned char __pad0[4];
159 unsigned int __st_ino;
160 unsigned int st_mode;
161 unsigned int st_nlink;
162 unsigned int st_uid;
163 unsigned int st_gid;
164 unsigned long long st_rdev;
165 unsigned char __pad3[4];
166 long long st_size;
167 unsigned int st_blksize;
168 unsigned long long st_blocks;
169 unsigned int st_atime;
170 unsigned int st_atime_nsec;
171 unsigned int st_mtime;
172 unsigned int st_mtime_nsec;
173 unsigned int st_ctime;
174 unsigned int st_ctime_nsec;
175 unsigned long long st_ino;
Elliott Hughes391c0d82014-04-03 17:50:14 -0700176}
Dmitry V. Levinf19836b2014-12-30 11:18:47 +0000177# if defined X86_64 || defined X32
Dmitry V. Levin5647cf82015-03-29 22:45:03 +0000178 ATTRIBUTE_PACKED
Dmitry V. Levinf19836b2014-12-30 11:18:47 +0000179# define STAT64_SIZE 96
180# else
181# define STAT64_SIZE 104
182# endif
Elliott Hughes391c0d82014-04-03 17:50:14 -0700183;
Dmitry V. Levin7b9bc442015-01-08 04:06:06 +0000184# define HAVE_STRUCT_STAT64 1
Dmitry V. Levinf19836b2014-12-30 11:18:47 +0000185# else /* !(AARCH64 || X86_64 || X32) */
186# warning FIXME: check whether struct stat64 definition is needed for this architecture!
187# endif
Dmitry V. Levin7b9bc442015-01-08 04:06:06 +0000188#endif /* STAT32_PERSONALITY && !HAVE_STRUCT_STAT64 */
Roland McGrathe6d0f712007-08-07 01:22:49 +0000189
Dmitry V. Levin7b9bc442015-01-08 04:06:06 +0000190#ifdef HAVE_STRUCT_STAT64
Dmitry V. Levinb8ad3932014-12-28 18:56:23 +0000191
192# define DO_PRINTSTAT do_printstat64
193# define STRUCT_STAT struct stat64
Dmitry V. Levinb8ad3932014-12-28 18:56:23 +0000194# include "printstat.h"
195
Wichert Akkerman328c5e71999-04-16 00:21:26 +0000196static void
Denys Vlasenko1d632462009-04-14 12:51:00 +0000197printstat64(struct tcb *tcp, long addr)
Ulrich Drepper7f02c4d1999-12-24 08:01:34 +0000198{
199 struct stat64 statbuf;
200
Dmitry V. Levinf19836b2014-12-30 11:18:47 +0000201# ifdef STAT64_SIZE
Roland McGrathe6d0f712007-08-07 01:22:49 +0000202 (void) sizeof(char[sizeof statbuf == STAT64_SIZE ? 1 : -1]);
Dmitry V. Levinf19836b2014-12-30 11:18:47 +0000203# endif
Roland McGrathe6d0f712007-08-07 01:22:49 +0000204
Dmitry V. Levin5f5fd0d2016-08-22 09:34:54 +0000205# if defined STAT32_PERSONALITY && !defined SPARC64
Dmitry V. Levinf19836b2014-12-30 11:18:47 +0000206 if (current_personality != STAT32_PERSONALITY) {
Elliott Hughes391c0d82014-04-03 17:50:14 -0700207 printstat(tcp, addr);
208 return;
209 }
Dmitry V. Levin5f5fd0d2016-08-22 09:34:54 +0000210# endif /* STAT32_PERSONALITY && !SPARC64 */
Dmitry V. Levinff896f72009-10-21 13:43:57 +0000211
Dmitry V. Levinb6d80ff2015-07-20 12:09:44 +0000212 if (!umove_or_printaddr(tcp, addr, &statbuf))
213 do_printstat64(tcp, &statbuf);
Ulrich Drepper7f02c4d1999-12-24 08:01:34 +0000214}
215
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000216SYS_FUNC(stat64)
Ulrich Drepper7f02c4d1999-12-24 08:01:34 +0000217{
Ulrich Drepper7f02c4d1999-12-24 08:01:34 +0000218 if (entering(tcp)) {
219 printpath(tcp, tcp->u_arg[0]);
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200220 tprints(", ");
Ulrich Drepper7f02c4d1999-12-24 08:01:34 +0000221 } else {
222 printstat64(tcp, tcp->u_arg[1]);
223 }
224 return 0;
Ulrich Drepper7f02c4d1999-12-24 08:01:34 +0000225}
226
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000227SYS_FUNC(fstat64)
Dmitry V. Levinc6ee0ec2015-01-08 01:14:53 +0000228{
Dmitry V. Levinc6ee0ec2015-01-08 01:14:53 +0000229 if (entering(tcp)) {
230 printfd(tcp, tcp->u_arg[0]);
231 tprints(", ");
232 } else {
233 printstat64(tcp, tcp->u_arg[1]);
234 }
235 return 0;
Dmitry V. Levinc6ee0ec2015-01-08 01:14:53 +0000236}
237
Dmitry V. Levinf19836b2014-12-30 11:18:47 +0000238#else
239
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000240SYS_FUNC(stat64)
Dmitry V. Levinf19836b2014-12-30 11:18:47 +0000241{
242 return sys_stat(tcp);
243}
244
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000245SYS_FUNC(fstat64)
Dmitry V. Levinf19836b2014-12-30 11:18:47 +0000246{
247 return sys_fstat(tcp);
248}
249
Dmitry V. Levin7b9bc442015-01-08 04:06:06 +0000250#endif /* HAVE_STRUCT_STAT64 */
Dmitry V. Levinf19836b2014-12-30 11:18:47 +0000251
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000252SYS_FUNC(newfstatat)
Dmitry V. Levin95ebf5a2006-10-13 20:25:12 +0000253{
254 if (entering(tcp)) {
Dmitry V. Levin31382132011-03-04 05:08:02 +0300255 print_dirfd(tcp, tcp->u_arg[0]);
Dmitry V. Levin95ebf5a2006-10-13 20:25:12 +0000256 printpath(tcp, tcp->u_arg[1]);
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200257 tprints(", ");
Dmitry V. Levin95ebf5a2006-10-13 20:25:12 +0000258 } else {
Dmitry V. Levin5f5fd0d2016-08-22 09:34:54 +0000259#if defined STAT32_PERSONALITY && !defined SPARC64
Dmitry V. Levinf19836b2014-12-30 11:18:47 +0000260 if (current_personality == STAT32_PERSONALITY)
Andreas Schwabd69fa492010-07-12 21:39:57 +0200261 printstat64(tcp, tcp->u_arg[2]);
Dmitry V. Levinf19836b2014-12-30 11:18:47 +0000262 else
263 printstat(tcp, tcp->u_arg[2]);
Dmitry V. Levin7b9bc442015-01-08 04:06:06 +0000264#elif defined HAVE_STRUCT_STAT64
Dmitry V. Levin95ebf5a2006-10-13 20:25:12 +0000265 printstat64(tcp, tcp->u_arg[2]);
266#else
267 printstat(tcp, tcp->u_arg[2]);
Dmitry V. Levin7b9bc442015-01-08 04:06:06 +0000268#endif /* STAT32_PERSONALITY || HAVE_STRUCT_STAT64 */
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200269 tprints(", ");
Dmitry V. Levin7989ad42012-03-13 23:26:01 +0000270 printflags(at_flags, tcp->u_arg[3], "AT_???");
Dmitry V. Levin95ebf5a2006-10-13 20:25:12 +0000271 }
272 return 0;
273}
Dmitry V. Levin95ebf5a2006-10-13 20:25:12 +0000274
Denys Vlasenko8435d672013-02-18 15:47:57 +0100275#if defined(HAVE_STRUCT___OLD_KERNEL_STAT)
Dmitry V. Levin1fb1c132014-12-28 19:10:58 +0000276
277static void
278convertoldstat(const struct __old_kernel_stat *oldbuf, struct stat *newbuf)
279{
280 memset(newbuf, 0, sizeof(*newbuf));
281 newbuf->st_dev = oldbuf->st_dev;
282 newbuf->st_ino = oldbuf->st_ino;
283 newbuf->st_mode = oldbuf->st_mode;
284 newbuf->st_nlink = oldbuf->st_nlink;
285 newbuf->st_uid = oldbuf->st_uid;
286 newbuf->st_gid = oldbuf->st_gid;
287 newbuf->st_rdev = oldbuf->st_rdev;
288 newbuf->st_size = oldbuf->st_size;
289 newbuf->st_atime = oldbuf->st_atime;
290 newbuf->st_mtime = oldbuf->st_mtime;
291 newbuf->st_ctime = oldbuf->st_ctime;
292}
293
294static void
295printoldstat(struct tcb *tcp, long addr)
296{
297 struct __old_kernel_stat statbuf;
298 struct stat newstatbuf;
299
Dmitry V. Levinb6d80ff2015-07-20 12:09:44 +0000300 if (!umove_or_printaddr(tcp, addr, &statbuf)) {
301 convertoldstat(&statbuf, &newstatbuf);
302 do_printstat(tcp, &newstatbuf);
Dmitry V. Levin1fb1c132014-12-28 19:10:58 +0000303 }
Dmitry V. Levin1fb1c132014-12-28 19:10:58 +0000304}
305
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000306SYS_FUNC(oldstat)
Dmitry V. Levin1fb1c132014-12-28 19:10:58 +0000307{
308 if (entering(tcp)) {
309 printpath(tcp, tcp->u_arg[0]);
310 tprints(", ");
311 } else {
312 printoldstat(tcp, tcp->u_arg[1]);
313 }
314 return 0;
315}
316
Dmitry V. Levina0bd3742015-04-07 01:36:50 +0000317SYS_FUNC(oldfstat)
Wichert Akkerman328c5e71999-04-16 00:21:26 +0000318{
Dmitry V. Levin31382132011-03-04 05:08:02 +0300319 if (entering(tcp)) {
320 printfd(tcp, tcp->u_arg[0]);
Denys Vlasenko60fe8c12011-09-01 10:00:28 +0200321 tprints(", ");
Dmitry V. Levin31382132011-03-04 05:08:02 +0300322 } else {
Wichert Akkerman328c5e71999-04-16 00:21:26 +0000323 printoldstat(tcp, tcp->u_arg[1]);
324 }
325 return 0;
326}
Dmitry V. Levin1fb1c132014-12-28 19:10:58 +0000327
328#endif /* HAVE_STRUCT___OLD_KERNEL_STAT */