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