usleep tests: Avoid failure due to known Cygwin 3.5.3 bug.
[gnulib.git] / tests / test-utime.c
blob00cee63265ef3163c0cc3fa3297e644de300b342
1 /* Tests of utime.
2 Copyright (C) 2017-2024 Free Software Foundation, Inc.
4 This program is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation, either version 3 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see <https://www.gnu.org/licenses/>. */
17 #include <config.h>
19 #include <utime.h>
21 #include <stdio.h>
22 #include <stdlib.h>
24 #include "ignore-value.h"
25 #include "macros.h"
27 #define BASE "test-utime.t"
29 #include "test-utimens-common.h"
31 /* If PRINT, warn before skipping tests with status 77. */
32 static int
33 test_utime (bool print)
35 struct stat st1;
36 struct stat st2;
38 ASSERT (close (creat (BASE "file", 0600)) == 0);
39 ASSERT (stat (BASE "file", &st1) == 0);
40 nap ();
41 ASSERT (utime (BASE "file", NULL) == 0);
42 ASSERT (stat (BASE "file", &st2) == 0);
43 ASSERT (0 <= utimecmp (BASE "file", &st2, &st1, UTIMECMP_TRUNCATE_SOURCE));
44 if (check_ctime)
45 ASSERT (ctime_compare (&st1, &st2) < 0);
47 /* On some NFS systems, the 'now' timestamp of creat or a NULL
48 utimbuf is determined by the server, but the 'now' timestamp
49 determined by time() is determined by the client; since the two
50 machines are not necessarily on the same clock, this is another
51 case where time can appear to go backwards. The rest of this
52 test cares about client time, so manually use time() to set
53 both times. */
54 struct utimbuf ts;
55 ts.actime = ts.modtime = time (NULL);
56 ASSERT (utime (BASE "file", &ts) == 0);
57 ASSERT (stat (BASE "file", &st1) == 0);
58 nap ();
61 /* Invalid arguments. */
62 errno = 0;
63 ASSERT (utime ("no_such", NULL) == -1);
64 ASSERT (errno == ENOENT);
65 errno = 0;
66 ASSERT (utime ("no_such/", NULL) == -1);
67 ASSERT (errno == ENOENT || errno == ENOTDIR);
68 errno = 0;
69 ASSERT (utime ("", NULL) == -1);
70 ASSERT (errno == ENOENT);
72 struct utimbuf ts;
73 ts.actime = ts.modtime = Y2K;
74 errno = 0;
75 ASSERT (utime (BASE "file/", &ts) == -1);
76 ASSERT (errno == ENOTDIR || errno == EINVAL);
78 ASSERT (stat (BASE "file", &st2) == 0);
79 ASSERT (st1.st_atime == st2.st_atime);
80 ASSERT (get_stat_atime_ns (&st1) == get_stat_atime_ns (&st2));
81 ASSERT (utimecmp (BASE "file", &st1, &st2, 0) == 0);
83 /* Set both times. */
85 struct utimbuf ts;
86 ts.actime = ts.modtime = Y2K;
87 ASSERT (utime (BASE "file", &ts) == 0);
88 ASSERT (stat (BASE "file", &st2) == 0);
89 ASSERT (st2.st_atime == Y2K);
90 ASSERT (0 <= get_stat_atime_ns (&st2));
91 ASSERT (get_stat_atime_ns (&st2) < BILLION / 2);
92 ASSERT (st2.st_mtime == Y2K);
93 ASSERT (0 <= get_stat_mtime_ns (&st2));
94 ASSERT (get_stat_mtime_ns (&st2) < BILLION);
95 if (check_ctime)
96 ASSERT (ctime_compare (&st1, &st2) < 0);
99 /* Make sure this dereferences symlinks. */
100 if (symlink (BASE "file", BASE "link"))
102 ASSERT (unlink (BASE "file") == 0);
103 if (test_exit_status != EXIT_SUCCESS)
104 return test_exit_status;
105 if (print)
106 fputs ("skipping test: symlinks not supported on this file system\n",
107 stderr);
108 return 77;
110 ASSERT (lstat (BASE "link", &st1) == 0);
111 ASSERT (st1.st_mtime != Y2K);
112 errno = 0;
113 ASSERT (utime (BASE "link/", NULL) == -1);
114 ASSERT (errno == ENOTDIR);
116 struct utimbuf ts;
117 ts.actime = ts.modtime = Y2K;
118 ASSERT (utime (BASE "link", &ts) == 0);
119 ASSERT (lstat (BASE "link", &st2) == 0);
120 /* Can't compare atimes, since lstat() changes symlink atime on cygwin. */
121 ASSERT (st1.st_mtime == st2.st_mtime);
122 ASSERT (stat (BASE "link", &st2) == 0);
123 ASSERT (st2.st_mtime == Y2K);
124 ASSERT (get_stat_mtime_ns (&st2) == 0);
127 /* Cleanup. */
128 ASSERT (unlink (BASE "link") == 0);
129 ASSERT (unlink (BASE "file") == 0);
130 return 0;
134 main (void)
136 int result1; /* Skip because of no symlink support. */
138 /* Clean up any trash from prior testsuite runs. */
139 ignore_value (system ("rm -rf " BASE "*"));
141 result1 = test_utime (true);
142 return (result1 ? result1 : test_exit_status);