blob: 8694f95529e1bc2398e24b1c870c4e67832ce19a [file] [log] [blame]
Dmitry V. Levincc2baf32015-12-05 00:01:56 +00001/*
Dmitry V. Levin6c52f2b2016-01-05 22:37:42 +00002 * Copyright (c) 2015-2016 Dmitry V. Levin <ldv@altlinux.org>
Dmitry V. Levincc2baf32015-12-05 00:01:56 +00003 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. The name of the author may not be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
Dmitry V. Levin6c52f2b2016-01-05 22:37:42 +000028#if defined HAVE_FTRUNCATE && defined HAVE_FUTIMENS
Dmitry V. Levincc2baf32015-12-05 00:01:56 +000029
Dmitry V. Levin7bbf8b52016-01-12 00:03:41 +000030# ifndef TEST_SYSCALL_STR
31# error TEST_SYSCALL_STR must be defined
Dmitry V. Levin6c52f2b2016-01-05 22:37:42 +000032# endif
Dmitry V. Levincc2baf32015-12-05 00:01:56 +000033# ifndef TEST_SYSCALL_INVOKE
34# error TEST_SYSCALL_INVOKE must be defined
35# endif
36# ifndef PRINT_SYSCALL_HEADER
37# error PRINT_SYSCALL_HEADER must be defined
38# endif
39# ifndef PRINT_SYSCALL_FOOTER
40# error PRINT_SYSCALL_FOOTER must be defined
41# endif
42
43# include <errno.h>
44# include <stdio.h>
45# include <stddef.h>
46# include <time.h>
47# include <unistd.h>
48
49# if defined MAJOR_IN_SYSMACROS
50# include <sys/sysmacros.h>
51# elif defined MAJOR_IN_MKDEV
52# include <sys/mkdev.h>
53# else
54# include <sys/types.h>
55# endif
56
57static void
58print_time(const time_t t)
59{
60 if (!t) {
61 printf("0");
62 return;
63 }
64
65 struct tm *p = localtime(&t);
66
67 if (p)
68 printf("%02d/%02d/%02d-%02d:%02d:%02d",
69 p->tm_year + 1900, p->tm_mon + 1, p->tm_mday,
70 p->tm_hour, p->tm_min, p->tm_sec);
71 else
72 printf("%llu", (unsigned long long) t);
73}
74
75typedef off_t libc_off_t;
76
77# ifdef USE_ASM_STAT
78# define stat libc_stat
79# define stat64 libc_stat64
80# endif
81# include <fcntl.h>
82# include <sys/stat.h>
83# ifdef USE_ASM_STAT
84# undef stat
85# undef stat64
86# endif
87
88# ifdef USE_ASM_STAT
89# undef st_atime
90# undef st_mtime
91# undef st_ctime
92# undef dev_t
93# undef gid_t
94# undef ino_t
95# undef loff_t
96# undef mode_t
97# undef nlink_t
98# undef off64_t
99# undef off_t
100# undef time_t
101# undef uid_t
102# define dev_t __kernel_dev_t
103# define gid_t __kernel_gid_t
104# define ino_t __kernel_ino_t
105# define loff_t __kernel_loff_t
106# define mode_t __kernel_mode_t
107# define nlink_t __kernel_nlink_t
108# define off64_t __kernel_off64_t
109# define off_t __kernel_off_t
110# define time_t __kernel_time_t
111# define uid_t __kernel_uid_t
112# include "asm_stat.h"
113# else
114# undef HAVE_STRUCT_STAT_ST_ATIME_NSEC
115# ifdef HAVE_STRUCT_STAT_ST_ATIM_TV_NSEC
116# define HAVE_STRUCT_STAT_ST_ATIME_NSEC 1
117# undef st_atime_nsec
118# define st_atime_nsec st_atim.tv_nsec
119# endif
120# undef HAVE_STRUCT_STAT_ST_MTIME_NSEC
121# ifdef HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC
122# define HAVE_STRUCT_STAT_ST_MTIME_NSEC 1
123# undef st_mtime_nsec
124# define st_mtime_nsec st_mtim.tv_nsec
125# endif
126# undef HAVE_STRUCT_STAT_ST_CTIME_NSEC
127# ifdef HAVE_STRUCT_STAT_ST_CTIM_TV_NSEC
128# define HAVE_STRUCT_STAT_ST_CTIME_NSEC 1
129# undef st_ctime_nsec
130# define st_ctime_nsec st_ctim.tv_nsec
131# endif
132# endif
133
134# ifndef STRUCT_STAT
135# define STRUCT_STAT struct stat
Dmitry V. Levin7bbf8b52016-01-12 00:03:41 +0000136# define STRUCT_STAT_STR "struct stat"
Dmitry V. Levincc2baf32015-12-05 00:01:56 +0000137# endif
138# ifndef SAMPLE_SIZE
139# define SAMPLE_SIZE 43147718418
140# endif
141
142static void
143print_ftype(const unsigned int mode)
144{
145 if (S_ISREG(mode))
146 printf("S_IFREG");
147 else if (S_ISDIR(mode))
148 printf("S_IFDIR");
149 else if (S_ISCHR(mode))
150 printf("S_IFCHR");
151 else if (S_ISBLK(mode))
152 printf("S_IFBLK");
153 else
154 printf("%#o", mode & S_IFMT);
155}
156
157static void
158print_perms(const unsigned int mode)
159{
160 printf("%#o", mode & ~S_IFMT);
161}
162
163static void
164print_stat(const STRUCT_STAT *st)
165{
166 printf("{st_dev=makedev(%u, %u)",
167 (unsigned int) major(st->st_dev),
168 (unsigned int) minor(st->st_dev));
Dmitry V. Levine67c8e42015-12-16 00:07:16 +0000169 printf(", st_ino=%llu", (unsigned long long) st->st_ino);
Dmitry V. Levincc2baf32015-12-05 00:01:56 +0000170 printf(", st_mode=");
171 print_ftype(st->st_mode);
172 printf("|");
173 print_perms(st->st_mode);
174 printf(", st_nlink=%u", (unsigned int) st->st_nlink);
175 printf(", st_uid=%u", (unsigned int) st->st_uid);
176 printf(", st_gid=%u", (unsigned int) st->st_gid);
177 printf(", st_blksize=%u", (unsigned int) st->st_blksize);
178 printf(", st_blocks=%u", (unsigned int) st->st_blocks);
179
180 switch (st->st_mode & S_IFMT) {
181 case S_IFCHR: case S_IFBLK:
182 printf(", st_rdev=makedev(%u, %u)",
183 (unsigned int) major(st->st_rdev),
184 (unsigned int) minor(st->st_rdev));
185 break;
186 default:
Dmitry V. Levine67c8e42015-12-16 00:07:16 +0000187 printf(", st_size=%llu", (unsigned long long) st->st_size);
Dmitry V. Levincc2baf32015-12-05 00:01:56 +0000188 }
189
190 printf(", st_atime=");
191 print_time(st->st_atime);
192# ifdef HAVE_STRUCT_STAT_ST_ATIME_NSEC
193 if (st->st_atime_nsec)
194 printf(".%09lu", (unsigned long) st->st_atime_nsec);
195# endif
196 printf(", st_mtime=");
197 print_time(st->st_mtime);
198# ifdef HAVE_STRUCT_STAT_ST_MTIME_NSEC
199 if (st->st_mtime_nsec)
200 printf(".%09lu", (unsigned long) st->st_mtime_nsec);
201# endif
202 printf(", st_ctime=");
203 print_time(st->st_ctime);
204# ifdef HAVE_STRUCT_STAT_ST_CTIME_NSEC
205 if (st->st_ctime_nsec)
206 printf(".%09lu", (unsigned long) st->st_ctime_nsec);
207# endif
208 printf("}");
209}
210
211static int
212create_sample(const char *fname, const libc_off_t size)
213{
214 static const struct timespec ts[] = {
215 {-10843, 135}, {-10841, 246}
216 };
217
218 (void) close(0);
219 if (open(fname, O_RDWR | O_CREAT | O_TRUNC, 0640)) {
220 perror(fname);
221 return 77;
222 }
223 if (ftruncate(0, size)) {
224 perror("ftruncate");
225 return 77;
226 }
227 if (futimens(0, ts)) {
228 perror("futimens");
229 return 77;
230 }
231 return 0;
232}
233
Dmitry V. Levincc2baf32015-12-05 00:01:56 +0000234int
235main(void)
236{
237 static const char sample[] = TEST_SYSCALL_STR ".sample";
238 STRUCT_STAT st[2];
239
240 int rc = create_sample(sample, SAMPLE_SIZE);
241 if (rc) {
242 (void) unlink(sample);
243 return rc;
244 }
245
246 if (TEST_SYSCALL_INVOKE(sample, st)) {
247 perror(TEST_SYSCALL_STR);
248 (void) unlink(sample);
249 return 77;
250 }
251 (void) unlink(sample);
252 if ((unsigned long long) SAMPLE_SIZE !=
253 (unsigned long long) st[0].st_size) {
254 fprintf(stderr, "Size mismatch: "
Dmitry V. Levine67c8e42015-12-16 00:07:16 +0000255 "requested size(%llu) != st_size(%llu)\n",
Dmitry V. Levincc2baf32015-12-05 00:01:56 +0000256 (unsigned long long) SAMPLE_SIZE,
257 (unsigned long long) st[0].st_size);
258 fprintf(stderr, "The most likely reason for this is incorrect"
259 " definition of %s.\n"
260 "Here is some diagnostics that might help:\n",
261 STRUCT_STAT_STR);
262 fprintf(stderr, "offsetof(%s, st_dev) = %zu"
263 ", sizeof(st_dev) = %zu\n",
264 STRUCT_STAT_STR, offsetof(STRUCT_STAT, st_dev),
265 sizeof(st[0].st_dev));
266 fprintf(stderr, "offsetof(%s, st_ino) = %zu"
267 ", sizeof(st_ino) = %zu\n",
268 STRUCT_STAT_STR, offsetof(STRUCT_STAT, st_ino),
269 sizeof(st[0].st_ino));
270 fprintf(stderr, "offsetof(%s, st_mode) = %zu"
271 ", sizeof(st_mode) = %zu\n",
272 STRUCT_STAT_STR, offsetof(STRUCT_STAT, st_mode),
273 sizeof(st[0].st_mode));
274 fprintf(stderr, "offsetof(%s, st_nlink) = %zu"
275 ", sizeof(st_nlink) = %zu\n",
276 STRUCT_STAT_STR, offsetof(STRUCT_STAT, st_nlink),
277 sizeof(st[0].st_nlink));
278 fprintf(stderr, "offsetof(%s, st_uid) = %zu"
279 ", sizeof(st_uid) = %zu\n",
280 STRUCT_STAT_STR, offsetof(STRUCT_STAT, st_uid),
281 sizeof(st[0].st_uid));
282 fprintf(stderr, "offsetof(%s, st_gid) = %zu"
283 ", sizeof(st_gid) = %zu\n",
284 STRUCT_STAT_STR, offsetof(STRUCT_STAT, st_gid),
285 sizeof(st[0].st_gid));
286 fprintf(stderr, "offsetof(%s, st_rdev) = %zu"
287 ", sizeof(st_rdev) = %zu\n",
288 STRUCT_STAT_STR, offsetof(STRUCT_STAT, st_rdev),
289 sizeof(st[0].st_rdev));
290 fprintf(stderr, "offsetof(%s, st_size) = %zu"
291 ", sizeof(st_size) = %zu\n",
292 STRUCT_STAT_STR, offsetof(STRUCT_STAT, st_size),
293 sizeof(st[0].st_size));
294 fprintf(stderr, "offsetof(%s, st_blksize) = %zu"
295 ", sizeof(st_blksize) = %zu\n",
296 STRUCT_STAT_STR, offsetof(STRUCT_STAT, st_blksize),
297 sizeof(st[0].st_blksize));
298 fprintf(stderr, "offsetof(%s, st_blocks) = %zu"
299 ", sizeof(st_blocks) = %zu\n",
300 STRUCT_STAT_STR, offsetof(STRUCT_STAT, st_blocks),
301 sizeof(st[0].st_blocks));
302 return 77;
303 }
304
305 PRINT_SYSCALL_HEADER(sample);
306 print_stat(st);
307 PRINT_SYSCALL_FOOTER;
308
309 puts("+++ exited with 0 +++");
310 return 0;
311}
312
313#else
314
Dmitry V. Levin6c52f2b2016-01-05 22:37:42 +0000315SKIP_MAIN_UNDEFINED("HAVE_FTRUNCATE && HAVE_FUTIMENS")
Dmitry V. Levincc2baf32015-12-05 00:01:56 +0000316
317#endif