blob: 2883f167b874f89f9fe7a2595a8ebc9f0fd6ac33 [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
Dmitry V. Levincc2baf32015-12-05 00:01:56 +000043# include <stdio.h>
44# include <stddef.h>
45# include <time.h>
46# include <unistd.h>
47
48# if defined MAJOR_IN_SYSMACROS
49# include <sys/sysmacros.h>
50# elif defined MAJOR_IN_MKDEV
51# include <sys/mkdev.h>
52# else
53# include <sys/types.h>
54# endif
55
56static void
57print_time(const time_t t)
58{
59 if (!t) {
60 printf("0");
61 return;
62 }
63
64 struct tm *p = localtime(&t);
65
66 if (p)
67 printf("%02d/%02d/%02d-%02d:%02d:%02d",
68 p->tm_year + 1900, p->tm_mon + 1, p->tm_mday,
69 p->tm_hour, p->tm_min, p->tm_sec);
70 else
71 printf("%llu", (unsigned long long) t);
72}
73
74typedef off_t libc_off_t;
75
76# ifdef USE_ASM_STAT
77# define stat libc_stat
78# define stat64 libc_stat64
79# endif
80# include <fcntl.h>
81# include <sys/stat.h>
82# ifdef USE_ASM_STAT
83# undef stat
84# undef stat64
85# endif
86
87# ifdef USE_ASM_STAT
88# undef st_atime
89# undef st_mtime
90# undef st_ctime
91# undef dev_t
92# undef gid_t
93# undef ino_t
94# undef loff_t
95# undef mode_t
96# undef nlink_t
97# undef off64_t
98# undef off_t
99# undef time_t
100# undef uid_t
101# define dev_t __kernel_dev_t
102# define gid_t __kernel_gid_t
103# define ino_t __kernel_ino_t
104# define loff_t __kernel_loff_t
105# define mode_t __kernel_mode_t
106# define nlink_t __kernel_nlink_t
107# define off64_t __kernel_off64_t
108# define off_t __kernel_off_t
109# define time_t __kernel_time_t
110# define uid_t __kernel_uid_t
111# include "asm_stat.h"
112# else
113# undef HAVE_STRUCT_STAT_ST_ATIME_NSEC
114# ifdef HAVE_STRUCT_STAT_ST_ATIM_TV_NSEC
115# define HAVE_STRUCT_STAT_ST_ATIME_NSEC 1
116# undef st_atime_nsec
117# define st_atime_nsec st_atim.tv_nsec
118# endif
119# undef HAVE_STRUCT_STAT_ST_MTIME_NSEC
120# ifdef HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC
121# define HAVE_STRUCT_STAT_ST_MTIME_NSEC 1
122# undef st_mtime_nsec
123# define st_mtime_nsec st_mtim.tv_nsec
124# endif
125# undef HAVE_STRUCT_STAT_ST_CTIME_NSEC
126# ifdef HAVE_STRUCT_STAT_ST_CTIM_TV_NSEC
127# define HAVE_STRUCT_STAT_ST_CTIME_NSEC 1
128# undef st_ctime_nsec
129# define st_ctime_nsec st_ctim.tv_nsec
130# endif
131# endif
132
133# ifndef STRUCT_STAT
134# define STRUCT_STAT struct stat
Dmitry V. Levin7bbf8b52016-01-12 00:03:41 +0000135# define STRUCT_STAT_STR "struct stat"
Dmitry V. Levincc2baf32015-12-05 00:01:56 +0000136# endif
137# ifndef SAMPLE_SIZE
138# define SAMPLE_SIZE 43147718418
139# endif
140
141static void
142print_ftype(const unsigned int mode)
143{
144 if (S_ISREG(mode))
145 printf("S_IFREG");
146 else if (S_ISDIR(mode))
147 printf("S_IFDIR");
148 else if (S_ISCHR(mode))
149 printf("S_IFCHR");
150 else if (S_ISBLK(mode))
151 printf("S_IFBLK");
152 else
153 printf("%#o", mode & S_IFMT);
154}
155
156static void
157print_perms(const unsigned int mode)
158{
159 printf("%#o", mode & ~S_IFMT);
160}
161
162static void
163print_stat(const STRUCT_STAT *st)
164{
165 printf("{st_dev=makedev(%u, %u)",
166 (unsigned int) major(st->st_dev),
167 (unsigned int) minor(st->st_dev));
Dmitry V. Levine67c8e42015-12-16 00:07:16 +0000168 printf(", st_ino=%llu", (unsigned long long) st->st_ino);
Dmitry V. Levincc2baf32015-12-05 00:01:56 +0000169 printf(", st_mode=");
170 print_ftype(st->st_mode);
171 printf("|");
172 print_perms(st->st_mode);
173 printf(", st_nlink=%u", (unsigned int) st->st_nlink);
174 printf(", st_uid=%u", (unsigned int) st->st_uid);
175 printf(", st_gid=%u", (unsigned int) st->st_gid);
176 printf(", st_blksize=%u", (unsigned int) st->st_blksize);
177 printf(", st_blocks=%u", (unsigned int) st->st_blocks);
178
179 switch (st->st_mode & S_IFMT) {
180 case S_IFCHR: case S_IFBLK:
181 printf(", st_rdev=makedev(%u, %u)",
182 (unsigned int) major(st->st_rdev),
183 (unsigned int) minor(st->st_rdev));
184 break;
185 default:
Dmitry V. Levine67c8e42015-12-16 00:07:16 +0000186 printf(", st_size=%llu", (unsigned long long) st->st_size);
Dmitry V. Levincc2baf32015-12-05 00:01:56 +0000187 }
188
189 printf(", st_atime=");
190 print_time(st->st_atime);
191# ifdef HAVE_STRUCT_STAT_ST_ATIME_NSEC
192 if (st->st_atime_nsec)
193 printf(".%09lu", (unsigned long) st->st_atime_nsec);
194# endif
195 printf(", st_mtime=");
196 print_time(st->st_mtime);
197# ifdef HAVE_STRUCT_STAT_ST_MTIME_NSEC
198 if (st->st_mtime_nsec)
199 printf(".%09lu", (unsigned long) st->st_mtime_nsec);
200# endif
201 printf(", st_ctime=");
202 print_time(st->st_ctime);
203# ifdef HAVE_STRUCT_STAT_ST_CTIME_NSEC
204 if (st->st_ctime_nsec)
205 printf(".%09lu", (unsigned long) st->st_ctime_nsec);
206# endif
207 printf("}");
208}
209
210static int
211create_sample(const char *fname, const libc_off_t size)
212{
213 static const struct timespec ts[] = {
214 {-10843, 135}, {-10841, 246}
215 };
216
217 (void) close(0);
218 if (open(fname, O_RDWR | O_CREAT | O_TRUNC, 0640)) {
219 perror(fname);
220 return 77;
221 }
222 if (ftruncate(0, size)) {
223 perror("ftruncate");
224 return 77;
225 }
226 if (futimens(0, ts)) {
227 perror("futimens");
228 return 77;
229 }
230 return 0;
231}
232
Dmitry V. Levincc2baf32015-12-05 00:01:56 +0000233int
234main(void)
235{
236 static const char sample[] = TEST_SYSCALL_STR ".sample";
237 STRUCT_STAT st[2];
238
239 int rc = create_sample(sample, SAMPLE_SIZE);
240 if (rc) {
241 (void) unlink(sample);
242 return rc;
243 }
244
245 if (TEST_SYSCALL_INVOKE(sample, st)) {
246 perror(TEST_SYSCALL_STR);
247 (void) unlink(sample);
248 return 77;
249 }
250 (void) unlink(sample);
251 if ((unsigned long long) SAMPLE_SIZE !=
252 (unsigned long long) st[0].st_size) {
253 fprintf(stderr, "Size mismatch: "
Dmitry V. Levine67c8e42015-12-16 00:07:16 +0000254 "requested size(%llu) != st_size(%llu)\n",
Dmitry V. Levincc2baf32015-12-05 00:01:56 +0000255 (unsigned long long) SAMPLE_SIZE,
256 (unsigned long long) st[0].st_size);
257 fprintf(stderr, "The most likely reason for this is incorrect"
258 " definition of %s.\n"
259 "Here is some diagnostics that might help:\n",
260 STRUCT_STAT_STR);
261 fprintf(stderr, "offsetof(%s, st_dev) = %zu"
262 ", sizeof(st_dev) = %zu\n",
263 STRUCT_STAT_STR, offsetof(STRUCT_STAT, st_dev),
264 sizeof(st[0].st_dev));
265 fprintf(stderr, "offsetof(%s, st_ino) = %zu"
266 ", sizeof(st_ino) = %zu\n",
267 STRUCT_STAT_STR, offsetof(STRUCT_STAT, st_ino),
268 sizeof(st[0].st_ino));
269 fprintf(stderr, "offsetof(%s, st_mode) = %zu"
270 ", sizeof(st_mode) = %zu\n",
271 STRUCT_STAT_STR, offsetof(STRUCT_STAT, st_mode),
272 sizeof(st[0].st_mode));
273 fprintf(stderr, "offsetof(%s, st_nlink) = %zu"
274 ", sizeof(st_nlink) = %zu\n",
275 STRUCT_STAT_STR, offsetof(STRUCT_STAT, st_nlink),
276 sizeof(st[0].st_nlink));
277 fprintf(stderr, "offsetof(%s, st_uid) = %zu"
278 ", sizeof(st_uid) = %zu\n",
279 STRUCT_STAT_STR, offsetof(STRUCT_STAT, st_uid),
280 sizeof(st[0].st_uid));
281 fprintf(stderr, "offsetof(%s, st_gid) = %zu"
282 ", sizeof(st_gid) = %zu\n",
283 STRUCT_STAT_STR, offsetof(STRUCT_STAT, st_gid),
284 sizeof(st[0].st_gid));
285 fprintf(stderr, "offsetof(%s, st_rdev) = %zu"
286 ", sizeof(st_rdev) = %zu\n",
287 STRUCT_STAT_STR, offsetof(STRUCT_STAT, st_rdev),
288 sizeof(st[0].st_rdev));
289 fprintf(stderr, "offsetof(%s, st_size) = %zu"
290 ", sizeof(st_size) = %zu\n",
291 STRUCT_STAT_STR, offsetof(STRUCT_STAT, st_size),
292 sizeof(st[0].st_size));
293 fprintf(stderr, "offsetof(%s, st_blksize) = %zu"
294 ", sizeof(st_blksize) = %zu\n",
295 STRUCT_STAT_STR, offsetof(STRUCT_STAT, st_blksize),
296 sizeof(st[0].st_blksize));
297 fprintf(stderr, "offsetof(%s, st_blocks) = %zu"
298 ", sizeof(st_blocks) = %zu\n",
299 STRUCT_STAT_STR, offsetof(STRUCT_STAT, st_blocks),
300 sizeof(st[0].st_blocks));
301 return 77;
302 }
303
304 PRINT_SYSCALL_HEADER(sample);
305 print_stat(st);
306 PRINT_SYSCALL_FOOTER;
307
308 puts("+++ exited with 0 +++");
309 return 0;
310}
311
312#else
313
Dmitry V. Levin6c52f2b2016-01-05 22:37:42 +0000314SKIP_MAIN_UNDEFINED("HAVE_FTRUNCATE && HAVE_FUTIMENS")
Dmitry V. Levincc2baf32015-12-05 00:01:56 +0000315
316#endif