mkdir-p: Depend on 'mkdir'.
[gnulib.git] / tests / test-utime.c
blobb3a8a9d36e158f866d8c6786df87c9cca31523c6
1 /* Tests of utime.
2 Copyright (C) 2017-2018 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 <stdbool.h>
22 #include <stdio.h>
23 #include <stdlib.h>
25 #include "ignore-value.h"
26 #include "macros.h"
28 #define BASE "test-utime.t"
30 #include "test-utimens-common.h"
32 /* If PRINT, warn before skipping tests with status 77. */
33 static int
34 test_utime (bool print)
36 struct stat st1;
37 struct stat st2;
39 ASSERT (close (creat (BASE "file", 0600)) == 0);
40 ASSERT (stat (BASE "file", &st1) == 0);
41 nap ();
42 ASSERT (utime (BASE "file", NULL) == 0);
43 ASSERT (stat (BASE "file", &st2) == 0);
44 ASSERT (0 <= utimecmp (BASE "file", &st2, &st1, UTIMECMP_TRUNCATE_SOURCE));
45 if (check_ctime)
46 ASSERT (ctime_compare (&st1, &st2) < 0);
48 /* On some NFS systems, the 'now' timestamp of creat or a NULL
49 utimbuf is determined by the server, but the 'now' timestamp
50 determined by time() is determined by the client; since the two
51 machines are not necessarily on the same clock, this is another
52 case where time can appear to go backwards. The rest of this
53 test cares about client time, so manually use time() to set
54 both times. */
55 struct utimbuf ts;
56 ts.actime = ts.modtime = time (NULL);
57 ASSERT (utime (BASE "file", &ts) == 0);
58 ASSERT (stat (BASE "file", &st1) == 0);
59 nap ();
62 /* Invalid arguments. */
63 errno = 0;
64 ASSERT (utime ("no_such", NULL) == -1);
65 ASSERT (errno == ENOENT);
66 errno = 0;
67 ASSERT (utime ("no_such/", NULL) == -1);
68 ASSERT (errno == ENOENT || errno == ENOTDIR);
69 errno = 0;
70 ASSERT (utime ("", NULL) == -1);
71 ASSERT (errno == ENOENT);
73 struct utimbuf ts;
74 ts.actime = ts.modtime = Y2K;
75 errno = 0;
76 ASSERT (utime (BASE "file/", &ts) == -1);
77 ASSERT (errno == ENOTDIR || errno == EINVAL);
79 ASSERT (stat (BASE "file", &st2) == 0);
80 ASSERT (st1.st_atime == st2.st_atime);
81 ASSERT (get_stat_atime_ns (&st1) == get_stat_atime_ns (&st2));
82 ASSERT (utimecmp (BASE "file", &st1, &st2, 0) == 0);
84 /* Set both times. */
86 struct utimbuf ts;
87 ts.actime = ts.modtime = Y2K;
88 ASSERT (utime (BASE "file", &ts) == 0);
89 ASSERT (stat (BASE "file", &st2) == 0);
90 ASSERT (st2.st_atime == Y2K);
91 ASSERT (0 <= get_stat_atime_ns (&st2));
92 ASSERT (get_stat_atime_ns (&st2) < BILLION / 2);
93 ASSERT (st2.st_mtime == Y2K);
94 ASSERT (0 <= get_stat_mtime_ns (&st2));
95 ASSERT (get_stat_mtime_ns (&st2) < BILLION);
96 if (check_ctime)
97 ASSERT (ctime_compare (&st1, &st2) < 0);
100 /* Make sure this dereferences symlinks. */
101 if (symlink (BASE "file", BASE "link"))
103 ASSERT (unlink (BASE "file") == 0);
104 if (print)
105 fputs ("skipping test: symlinks not supported on this file system\n",
106 stderr);
107 return 77;
109 ASSERT (lstat (BASE "link", &st1) == 0);
110 ASSERT (st1.st_mtime != Y2K);
111 errno = 0;
112 ASSERT (utime (BASE "link/", NULL) == -1);
113 ASSERT (errno == ENOTDIR);
115 struct utimbuf ts;
116 ts.actime = ts.modtime = Y2K;
117 ASSERT (utime (BASE "link", &ts) == 0);
118 ASSERT (lstat (BASE "link", &st2) == 0);
119 /* Can't compare atimes, since lstat() changes symlink atime on cygwin. */
120 ASSERT (st1.st_mtime == st2.st_mtime);
121 ASSERT (stat (BASE "link", &st2) == 0);
122 ASSERT (st2.st_mtime == Y2K);
123 ASSERT (get_stat_mtime_ns (&st2) == 0);
126 /* Cleanup. */
127 ASSERT (unlink (BASE "link") == 0);
128 ASSERT (unlink (BASE "file") == 0);
129 return 0;
133 main (void)
135 int result1; /* Skip because of no symlink support. */
137 /* Clean up any trash from prior testsuite runs. */
138 ignore_value (system ("rm -rf " BASE "*"));
140 result1 = test_utime (true);
141 return result1;