]> granicus.if.org Git - strace/blob - tests/utimensat.c
Remove XLAT_END
[strace] / tests / utimensat.c
1 /*
2  * Check decoding of utimensat syscall.
3  *
4  * Copyright (c) 2015-2017 Dmitry V. Levin <ldv@altlinux.org>
5  * Copyright (c) 2015-2019 The strace developers.
6  * All rights reserved.
7  *
8  * SPDX-License-Identifier: GPL-2.0-or-later
9  */
10
11 #include "tests.h"
12 #include <fcntl.h>
13 #include <stdint.h>
14 #include <stdio.h>
15 #include <sys/stat.h>
16 #include <sys/time.h>
17 #include <unistd.h>
18 #include "scno.h"
19
20 #if defined __NR_utimensat && defined UTIME_NOW && defined UTIME_OMIT
21
22 # if SIZEOF_KERNEL_LONG_T == 4
23 #  define big_tv_sec "-559038737"
24 #  define huge_tv_sec "-559038737"
25 # else
26 #  define big_tv_sec "3735928559"
27 #  define huge_tv_sec "-3819351491602432273"
28 # endif
29
30 # if XLAT_RAW
31 #  define str_at_fdcwd                  "-100"
32 #  define str_at_symlink_nofollow       "0x100"
33 #  define str_at_removedir              "0x200"
34 #  define str_flags1                    "0x600"
35 #  define str_flags2                    "0xffffffff"
36 #  define str_utime_now_omit \
37         "[{tv_sec=" big_tv_sec ", tv_nsec=1073741823}, " \
38         "{tv_sec=" huge_tv_sec ", tv_nsec=1073741822}]"
39 # elif XLAT_VERBOSE
40 #  define str_at_fdcwd                  "-100 /* AT_FDCWD */"
41 #  define str_at_symlink_nofollow       "0x100 /* AT_SYMLINK_NOFOLLOW */"
42 #  define str_at_removedir              "0x200 /* AT_REMOVEDIR */"
43 #  define str_flags1 \
44         "0x600 /* AT_REMOVEDIR|AT_SYMLINK_FOLLOW */"
45 #  define str_flags2 \
46         "0xffffffff /* AT_SYMLINK_NOFOLLOW|AT_REMOVEDIR|AT_SYMLINK_FOLLOW" \
47         "|AT_NO_AUTOMOUNT|AT_EMPTY_PATH|AT_RECURSIVE|0xffff60ff */"
48 #  define str_utime_now_omit \
49         "[{tv_sec=" big_tv_sec ", tv_nsec=1073741823} /* UTIME_NOW */, " \
50         "{tv_sec=" huge_tv_sec ", tv_nsec=1073741822} /* UTIME_OMIT */]"
51 # else
52 #  define str_at_fdcwd                  "AT_FDCWD"
53 #  define str_at_symlink_nofollow       "AT_SYMLINK_NOFOLLOW"
54 #  define str_at_removedir              "AT_REMOVEDIR"
55 #  define str_flags1                    "AT_REMOVEDIR|AT_SYMLINK_FOLLOW"
56 #  define str_flags2 \
57         "AT_SYMLINK_NOFOLLOW|AT_REMOVEDIR|AT_SYMLINK_FOLLOW" \
58         "|AT_NO_AUTOMOUNT|AT_EMPTY_PATH|AT_RECURSIVE|0xffff60ff"
59 #  define str_utime_now_omit            "[UTIME_NOW, UTIME_OMIT]"
60 # endif
61
62 static void
63 print_ts(const struct timespec *ts)
64 {
65         printf("{tv_sec=%lld, tv_nsec=%llu}", (long long) ts->tv_sec,
66                 zero_extend_signed_to_ull(ts->tv_nsec));
67         print_time_t_nsec(ts->tv_sec,
68                           zero_extend_signed_to_ull(ts->tv_nsec), 1);
69 }
70
71 static const char *errstr;
72
73 static long
74 k_utimensat(const kernel_ulong_t dirfd,
75             const kernel_ulong_t pathname,
76             const kernel_ulong_t times,
77             const kernel_ulong_t flags)
78 {
79         long rc = syscall(__NR_utimensat, dirfd, pathname, times, flags);
80         errstr = sprintrc(rc);
81         return rc;
82 }
83
84 int
85 main(void)
86 {
87         static const kernel_ulong_t bogus_fd =
88                 (kernel_ulong_t) 0xbadc0deddeadbeef;
89         static const kernel_ulong_t kfdcwd =
90                 (kernel_ulong_t) 0xdefaced00000000 | -100U;
91         static const char proto_fname[] = "utimensat\nfilename";
92         static const char qname[] = "\"utimensat\\nfilename\"";
93
94         char *const fname = tail_memdup(proto_fname, sizeof(proto_fname));
95         const kernel_ulong_t kfname = (uintptr_t) fname;
96         struct timespec *const ts = tail_alloc(sizeof(*ts) * 2);
97
98         (void) close(0);
99
100         /* dirfd */
101         k_utimensat(0, kfname, 0, 0);
102         printf("utimensat(0, %s, NULL, 0) = %s\n", qname, errstr);
103
104         k_utimensat(bogus_fd, kfname, 0, 0);
105         printf("utimensat(%d, %s, NULL, 0) = %s\n",
106                (int) bogus_fd, qname, errstr);
107
108         k_utimensat(-100U, kfname, 0, 0);
109         printf("utimensat(" str_at_fdcwd ", %s, NULL, 0) = %s\n", qname, errstr);
110
111         k_utimensat(kfdcwd, kfname, 0, 0);
112         printf("utimensat(" str_at_fdcwd ", %s, NULL, 0) = %s\n", qname, errstr);
113
114         /* pathname */
115         k_utimensat(kfdcwd, 0, 0, 0);
116         printf("utimensat(" str_at_fdcwd ", NULL, NULL, 0) = %s\n", errstr);
117
118         k_utimensat(kfdcwd, kfname + sizeof(proto_fname) - 1, 0, 0);
119         printf("utimensat(" str_at_fdcwd ", \"\", NULL, 0) = %s\n", errstr);
120
121         fname[sizeof(proto_fname) - 1] = '+';
122         k_utimensat(kfdcwd, kfname, 0, 0);
123         fname[sizeof(proto_fname) - 1] = '\0';
124         printf("utimensat(" str_at_fdcwd ", %p, NULL, 0) = %s\n", fname, errstr);
125
126         if (F8ILL_KULONG_SUPPORTED) {
127                 k_utimensat(kfdcwd, f8ill_ptr_to_kulong(fname), 0, 0);
128                 printf("utimensat(" str_at_fdcwd ", %#jx, NULL, 0) = %s\n",
129                        (uintmax_t) f8ill_ptr_to_kulong(fname), errstr);
130         }
131
132         /* times */
133         k_utimensat(kfdcwd, kfname, (uintptr_t) (ts + 1), 0);
134         printf("utimensat(" str_at_fdcwd ", %s, %p, 0) = %s\n",
135                qname, ts + 1, errstr);
136
137         k_utimensat(kfdcwd, kfname, (uintptr_t) (ts + 2), 0);
138         printf("utimensat(" str_at_fdcwd ", %s, %p, 0)"
139                " = %s\n", qname, ts + 2, errstr);
140
141         ts[0].tv_sec = 1492358706;
142         ts[0].tv_nsec = 123456789;
143         ts[1].tv_sec = 1492357068;
144         ts[1].tv_nsec = 234567890;
145
146         k_utimensat(kfdcwd, kfname, (uintptr_t) ts, 0x100);
147         printf("utimensat(" str_at_fdcwd ", %s, [", qname);
148         print_ts(&ts[0]);
149         printf(", ");
150         print_ts(&ts[1]);
151         printf("], " str_at_symlink_nofollow ") = %s\n", errstr);
152
153         ts[0].tv_sec = -1;
154         ts[0].tv_nsec = 2000000000;
155         ts[1].tv_sec = (time_t) -0x100000001LL;
156         ts[1].tv_nsec = 2345678900U;
157
158         k_utimensat(kfdcwd, kfname, (uintptr_t) ts, 0x100);
159         printf("utimensat(" str_at_fdcwd ", %s, [", qname);
160         print_ts(&ts[0]);
161         printf(", ");
162         print_ts(&ts[1]);
163         printf("], " str_at_symlink_nofollow ") = %s\n", errstr);
164
165         ts[0].tv_sec = 0;
166         ts[0].tv_nsec = 0;
167         ts[1].tv_sec = (time_t) 0xcafef00ddeadbeefLL;
168         ts[1].tv_nsec = 0;
169
170         k_utimensat(kfdcwd, kfname, (uintptr_t) ts, 0x100);
171         printf("utimensat(" str_at_fdcwd ", %s, [", qname);
172         print_ts(&ts[0]);
173         printf(", ");
174         print_ts(&ts[1]);
175         printf("], " str_at_symlink_nofollow ") = %s\n", errstr);
176
177         ts[0].tv_sec = 0xdeadbeefU;
178         ts[0].tv_nsec = 0xfacefeedU;
179         ts[1].tv_sec = (time_t) 0xcafef00ddeadbeefLL;
180         ts[1].tv_nsec = (long) 0xbadc0dedfacefeedLL;
181
182         k_utimensat(kfdcwd, kfname, (uintptr_t) ts, 0x100);
183         printf("utimensat(" str_at_fdcwd ", %s, [", qname);
184         print_ts(&ts[0]);
185         printf(", ");
186         print_ts(&ts[1]);
187         printf("], " str_at_symlink_nofollow ") = %s\n", errstr);
188
189         ts[0].tv_nsec = UTIME_NOW;
190         ts[1].tv_nsec = UTIME_OMIT;
191         k_utimensat(kfdcwd, kfname, (uintptr_t) ts, 0x100);
192         printf("utimensat(" str_at_fdcwd ", %s, " str_utime_now_omit
193                ", " str_at_symlink_nofollow ") = %s\n", qname, errstr);
194
195         if (F8ILL_KULONG_SUPPORTED) {
196                 k_utimensat(kfdcwd, kfname, f8ill_ptr_to_kulong(ts), 0);
197                 printf("utimensat(" str_at_fdcwd ", %s, %#jx, 0) = %s\n",
198                        qname, (uintmax_t) f8ill_ptr_to_kulong(ts), errstr);
199         }
200
201         /* flags */
202         k_utimensat(kfdcwd, kfname, (uintptr_t) ts,
203                     (kernel_ulong_t) 0xdefaced00000200);
204         printf("utimensat(" str_at_fdcwd ", %s, " str_utime_now_omit
205                ", " str_at_removedir ") = %s\n",
206                qname, errstr);
207
208         k_utimensat(kfdcwd, kfname, (uintptr_t) ts,
209                     (kernel_ulong_t) 0xdefaced00000600);
210         printf("utimensat(" str_at_fdcwd ", %s, " str_utime_now_omit
211                ", " str_flags1 ") = %s\n",
212                qname, errstr);
213
214         k_utimensat(kfdcwd, kfname, (uintptr_t) ts, (kernel_ulong_t) -1ULL);
215         printf("utimensat(" str_at_fdcwd ", %s, " str_utime_now_omit
216                ", " str_flags2 ") = %s\n",
217                qname, errstr);
218
219         puts("+++ exited with 0 +++");
220         return 0;
221 }
222
223 #else
224
225 SKIP_MAIN_UNDEFINED("__NR_utimensat && UTIME_NOW && UTIME_OMIT")
226
227 #endif