Update NEWS.
[glibc.git] / io / tst-futimesat.c
blobf09907b0395f7f8605613353c7fb4f17fb2827a8
1 /* futimesat basic tests.
2 Copyright (C) 2021-2022 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
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.
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.
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/>. */
19 #include <dirent.h>
20 #include <errno.h>
21 #include <fcntl.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <unistd.h>
26 #include <sys/stat.h>
27 #include <sys/time.h>
29 #include <support/test-driver.h>
30 #include <support/temp_file.h>
32 #ifndef struct_stat
33 # define struct_stat struct stat64
34 # define fstat fstat64
35 # define fstatat fstatat64
36 #endif
38 static int dir_fd;
40 static void
41 prepare (int argc, char *argv[])
43 size_t test_dir_len = strlen (test_dir);
44 static const char dir_name[] = "/tst-futimesat.XXXXXX";
46 size_t dirbuflen = test_dir_len + sizeof (dir_name);
47 char *dirbuf = malloc (dirbuflen);
48 if (dirbuf == NULL)
50 puts ("out of memory");
51 exit (1);
54 snprintf (dirbuf, dirbuflen, "%s%s", test_dir, dir_name);
55 if (mkdtemp (dirbuf) == NULL)
57 puts ("cannot create temporary directory");
58 exit (1);
61 add_temp_file (dirbuf);
63 dir_fd = open (dirbuf, O_RDONLY | O_DIRECTORY);
64 if (dir_fd == -1)
66 puts ("cannot open directory");
67 exit (1);
70 #define PREPARE prepare
72 static int
73 do_test (void)
75 /* fdopendir takes over the descriptor, make a copy. */
76 int dupfd = dup (dir_fd);
77 if (dupfd == -1)
79 puts ("dup failed");
80 return 1;
82 if (lseek (dupfd, 0, SEEK_SET) != 0)
84 puts ("1st lseek failed");
85 return 1;
88 /* The directory should be empty safe the . and .. files. */
89 DIR *dir = fdopendir (dupfd);
90 if (dir == NULL)
92 puts ("fdopendir failed");
93 return 1;
95 struct dirent64 *d;
96 while ((d = readdir64 (dir)) != NULL)
97 if (strcmp (d->d_name, ".") != 0 && strcmp (d->d_name, "..") != 0)
99 printf ("temp directory contains file \"%s\"\n", d->d_name);
100 return 1;
102 closedir (dir);
104 /* Try to create a file. */
105 int fd = openat (dir_fd, "some-file", O_CREAT|O_RDWR|O_EXCL, 0666);
106 if (fd == -1)
108 if (errno == ENOSYS)
110 puts ("*at functions not supported");
111 return 0;
114 puts ("file creation failed");
115 return 1;
117 write (fd, "hello", 5);
118 puts ("file created");
120 struct_stat st1;
121 if (fstat (fd, &st1) != 0)
123 puts ("fstat64 failed");
124 return 1;
127 close (fd);
129 struct timeval tv[2];
130 tv[0].tv_sec = st1.st_atime + 1;
131 tv[0].tv_usec = 0;
132 tv[1].tv_sec = st1.st_mtime + 1;
133 tv[1].tv_usec = 0;
134 if (futimesat (dir_fd, "some-file", tv) != 0)
136 puts ("futimesat failed");
137 return 1;
140 struct_stat st2;
141 if (fstatat (dir_fd, "some-file", &st2, 0) != 0)
143 puts ("fstatat64 failed");
144 return 1;
147 if (st2.st_mtime != tv[1].tv_sec
148 #ifdef _STATBUF_ST_NSEC
149 || st2.st_mtim.tv_nsec != 0
150 #endif
153 puts ("stat shows different mtime");
154 return 1;
158 if (unlinkat (dir_fd, "some-file", 0) != 0)
160 puts ("unlinkat failed");
161 return 1;
164 close (dir_fd);
166 return 0;
169 #include <support/test-driver.c>