1 /* Common tests for utimensat routines.
2 Copyright (C) 2021-2022 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
4
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, see
17 <https://www.gnu.org/licenses/>. */
18
19 #include <array_length.h>
20 #include <inttypes.h>
21 #include <support/support.h>
22 #include <support/temp_file.h>
23 #include <stdio.h>
24
25 static int temp_fd = -1;
26 static char *testfile;
27 static char *testlink;
28
29 const static struct {
30 int64_t v1;
31 int64_t v2;
32 } tests[] = {
33 /* Some arbitrary date before Y2038. */
34 { 0x60ECA720LL, 0x60eca721LL },
35 /* Y2038 threshold minus 2 and 1 seconds. */
36 { 0x7FFFFFFELL, 0x7FFFFFFFLL },
37 /* Y2038 threshold plus 1 and 2 seconds. */
38 { 0x80000001LL, 0x80000002LL },
39 /* Around Y2038 threshold. */
40 { 0x7FFFFFFELL, 0x80000002LL },
41 /* Y2106 threshold minus 2 and 1 seconds. */
42 { 0x100000000LL, 0xFFFFFFFELL },
43 /* Y2106 threshold plus 1 and 2 seconds. */
44 { 0x100000001LL, 0x100000002LL },
45 /* Around Y2106 threshold. */
46 { 0xFFFFFFFELL, 0xFFFFFFFELL },
47 };
48
49 #define PREPARE do_prepare
50 static void
do_prepare(int argc,char * argv[])51 do_prepare (int argc, char *argv[])
52 {
53 temp_fd = create_temp_file ("utime", &testfile);
54 TEST_VERIFY_EXIT (temp_fd > 0);
55
56 testlink = xasprintf ("%s-symlink", testfile);
57 xsymlink (testfile, testlink);
58 add_temp_file (testlink);
59 }
60
61 static int
do_test(void)62 do_test (void)
63 {
64 if (sizeof (time_t) == 8 && !support_path_support_time64 (testfile))
65 FAIL_UNSUPPORTED ("File %s does not support 64-bit timestamps",
66 testfile);
67
68 bool y2106 = support_path_support_time64_value (testfile,
69 0x100000001LL,
70 0x100000002LL);
71
72 for (int i = 0; i < array_length (tests); i++)
73 {
74 /* Check if we run on port with 32 bit time_t size. */
75 time_t t;
76 if (__builtin_add_overflow (tests[i].v1, 0, &t)
77 || __builtin_add_overflow (tests[i].v2, 0, &t))
78 {
79 printf ("warning: skipping tests[%d] { %" PRIx64 ", %" PRIx64 " }: "
80 "time_t overflows\n", i, tests[i].v1, tests[i].v2);
81 continue;
82 }
83
84 if (tests[i].v1 >= 0x100000000LL && !y2106)
85 {
86 printf ("warning: skipping tests[%d] { %" PRIx64 ", %" PRIx64 " }: "
87 "unsupported timestamp value\n",
88 i, tests[i].v1, tests[i].v2);
89 continue;
90 }
91
92 TEST_CALL (testfile, temp_fd, testlink, tests[i].v1, tests[i].v2);
93 }
94
95 return 0;
96 }
97
98 #include <support/test-driver.c>
99