1 1.9 riastrad /* $NetBSD: t_utimensat.c,v 1.9 2024/08/10 15:20:22 riastradh Exp $ */ 2 1.1 manu 3 1.1 manu /*- 4 1.1 manu * Copyright (c) 2012 The NetBSD Foundation, Inc. 5 1.1 manu * All rights reserved. 6 1.1 manu * 7 1.1 manu * This code is derived from software contributed to The NetBSD Foundation 8 1.1 manu * by Emmanuel Dreyfus. 9 1.1 manu * 10 1.1 manu * Redistribution and use in source and binary forms, with or without 11 1.1 manu * modification, are permitted provided that the following conditions 12 1.1 manu * are met: 13 1.1 manu * 1. Redistributions of source code must retain the above copyright 14 1.1 manu * notice, this list of conditions and the following disclaimer. 15 1.1 manu * 2. Redistributions in binary form must reproduce the above copyright 16 1.1 manu * notice, this list of conditions and the following disclaimer in the 17 1.1 manu * documentation and/or other materials provided with the distribution. 18 1.1 manu * 19 1.1 manu * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 1.1 manu * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 1.1 manu * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 1.1 manu * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 1.1 manu * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 1.1 manu * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 1.1 manu * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 1.1 manu * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 1.1 manu * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 1.1 manu * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 1.1 manu * POSSIBILITY OF SUCH DAMAGE. 30 1.1 manu */ 31 1.1 manu #include <sys/cdefs.h> 32 1.9 riastrad __RCSID("$NetBSD: t_utimensat.c,v 1.9 2024/08/10 15:20:22 riastradh Exp $"); 33 1.1 manu 34 1.6 christos #include <sys/param.h> 35 1.9 riastrad 36 1.6 christos #include <sys/stat.h> 37 1.9 riastrad #include <sys/statvfs.h> 38 1.6 christos #include <sys/time.h> 39 1.9 riastrad 40 1.1 manu #include <atf-c.h> 41 1.1 manu #include <errno.h> 42 1.1 manu #include <fcntl.h> 43 1.1 manu #include <limits.h> 44 1.1 manu #include <paths.h> 45 1.1 manu #include <stdio.h> 46 1.1 manu #include <string.h> 47 1.1 manu #include <unistd.h> 48 1.1 manu 49 1.8 riastrad #include "h_macros.h" 50 1.8 riastrad 51 1.1 manu #define DIR "dir" 52 1.1 manu #define FILE "dir/utimensat" 53 1.1 manu #define BASEFILE "utimensat" 54 1.1 manu #define LINK "dir/symlink" 55 1.1 manu #define BASELINK "symlink" 56 1.1 manu #define FILEERR "dir/symlink" 57 1.1 manu 58 1.8 riastrad static const struct timespec tptr[] = { 59 1.3 martin { 0x12345678, 987654321 }, 60 1.3 martin { 0x15263748, 123456789 }, 61 1.1 manu }; 62 1.1 manu 63 1.8 riastrad static void 64 1.9 riastrad checkstattime(const struct stat *st, const struct statvfs *fs) 65 1.8 riastrad { 66 1.8 riastrad 67 1.9 riastrad if ((fs->f_flag & ST_NOATIME) == 0) { 68 1.9 riastrad ATF_CHECK_EQ_MSG(st->st_atimespec.tv_sec, tptr[0].tv_sec, 69 1.9 riastrad "st->st_atimespec.tv_sec=%lld tptr[0].tv_sec=%lld", 70 1.9 riastrad (long long)st->st_atimespec.tv_sec, 71 1.9 riastrad (long long)tptr[0].tv_sec); 72 1.9 riastrad ATF_CHECK_EQ_MSG(st->st_atimespec.tv_nsec, tptr[0].tv_nsec, 73 1.9 riastrad "st->st_atimespec.tv_nsec=%ld tptr[0].tv_nsec=%ld", 74 1.9 riastrad (long)st->st_atimespec.tv_nsec, (long)tptr[0].tv_nsec); 75 1.9 riastrad } 76 1.8 riastrad ATF_CHECK_EQ_MSG(st->st_mtimespec.tv_sec, tptr[1].tv_sec, 77 1.8 riastrad "st->st_mtimespec.tv_sec=%lld tptr[1].tv_sec=%lld", 78 1.8 riastrad (long long)st->st_mtimespec.tv_sec, (long long)tptr[1].tv_sec); 79 1.8 riastrad ATF_CHECK_EQ_MSG(st->st_mtimespec.tv_nsec, tptr[1].tv_nsec, 80 1.8 riastrad "st->st_mtimespec.tv_nsec=%ld tptr[1].tv_nsec=%ld", 81 1.8 riastrad (long)st->st_mtimespec.tv_nsec, (long)tptr[1].tv_nsec); 82 1.8 riastrad } 83 1.8 riastrad 84 1.5 jmmv ATF_TC(utimensat_fd); 85 1.1 manu ATF_TC_HEAD(utimensat_fd, tc) 86 1.1 manu { 87 1.1 manu atf_tc_set_md_var(tc, "descr", "See that utimensat works with fd"); 88 1.1 manu } 89 1.1 manu ATF_TC_BODY(utimensat_fd, tc) 90 1.1 manu { 91 1.1 manu int dfd; 92 1.1 manu int fd; 93 1.1 manu struct stat st; 94 1.9 riastrad struct statvfs fs; 95 1.1 manu 96 1.8 riastrad RL(mkdir(DIR, 0755)); 97 1.8 riastrad RL(fd = open(FILE, O_CREAT|O_RDWR, 0644)); 98 1.8 riastrad RL(close(fd)); 99 1.8 riastrad 100 1.8 riastrad RL(dfd = open(DIR, O_RDONLY, 0)); 101 1.8 riastrad RL(utimensat(dfd, BASEFILE, tptr, 0)); 102 1.8 riastrad RL(close(dfd)); 103 1.8 riastrad 104 1.8 riastrad RL(stat(FILE, &st)); 105 1.9 riastrad RL(statvfs(FILE, &fs)); 106 1.9 riastrad checkstattime(&st, &fs); 107 1.1 manu } 108 1.1 manu 109 1.5 jmmv ATF_TC(utimensat_fdcwd); 110 1.1 manu ATF_TC_HEAD(utimensat_fdcwd, tc) 111 1.1 manu { 112 1.8 riastrad atf_tc_set_md_var(tc, "descr", 113 1.8 riastrad "See that utimensat works with fd as AT_FDCWD"); 114 1.1 manu } 115 1.1 manu ATF_TC_BODY(utimensat_fdcwd, tc) 116 1.1 manu { 117 1.1 manu int fd; 118 1.1 manu struct stat st; 119 1.9 riastrad struct statvfs fs; 120 1.1 manu 121 1.8 riastrad RL(mkdir(DIR, 0755)); 122 1.8 riastrad RL(fd = open(FILE, O_CREAT|O_RDWR, 0644)); 123 1.8 riastrad RL(close(fd)); 124 1.8 riastrad 125 1.8 riastrad RL(chdir(DIR)); 126 1.8 riastrad RL(utimensat(AT_FDCWD, BASEFILE, tptr, 0)); 127 1.8 riastrad 128 1.8 riastrad RL(stat(BASEFILE, &st)); 129 1.9 riastrad RL(statvfs(BASEFILE, &fs)); 130 1.9 riastrad checkstattime(&st, &fs); 131 1.1 manu } 132 1.1 manu 133 1.5 jmmv ATF_TC(utimensat_fdcwderr); 134 1.1 manu ATF_TC_HEAD(utimensat_fdcwderr, tc) 135 1.1 manu { 136 1.8 riastrad atf_tc_set_md_var(tc, "descr", 137 1.8 riastrad "See that utimensat fails with fd as AT_FDCWD and bad path"); 138 1.1 manu } 139 1.1 manu ATF_TC_BODY(utimensat_fdcwderr, tc) 140 1.1 manu { 141 1.8 riastrad RL(mkdir(DIR, 0755)); 142 1.8 riastrad ATF_CHECK_ERRNO(ENOENT, utimensat(AT_FDCWD, FILEERR, tptr, 0) == -1); 143 1.1 manu } 144 1.1 manu 145 1.5 jmmv ATF_TC(utimensat_fderr1); 146 1.1 manu ATF_TC_HEAD(utimensat_fderr1, tc) 147 1.1 manu { 148 1.8 riastrad atf_tc_set_md_var(tc, "descr", 149 1.8 riastrad "See that utimensat fail with bad path"); 150 1.1 manu } 151 1.1 manu ATF_TC_BODY(utimensat_fderr1, tc) 152 1.1 manu { 153 1.1 manu int dfd; 154 1.1 manu 155 1.8 riastrad RL(mkdir(DIR, 0755)); 156 1.8 riastrad RL(dfd = open(DIR, O_RDONLY, 0)); 157 1.8 riastrad ATF_CHECK_ERRNO(ENOENT, utimensat(dfd, FILEERR, tptr, 0) == -1); 158 1.8 riastrad RL(close(dfd)); 159 1.1 manu } 160 1.1 manu 161 1.5 jmmv ATF_TC(utimensat_fderr2); 162 1.1 manu ATF_TC_HEAD(utimensat_fderr2, tc) 163 1.1 manu { 164 1.8 riastrad atf_tc_set_md_var(tc, "descr", 165 1.8 riastrad "See that utimensat fails with bad fdat"); 166 1.1 manu } 167 1.1 manu ATF_TC_BODY(utimensat_fderr2, tc) 168 1.1 manu { 169 1.1 manu int dfd; 170 1.1 manu int fd; 171 1.1 manu char cwd[MAXPATHLEN]; 172 1.1 manu 173 1.8 riastrad RL(mkdir(DIR, 0755)); 174 1.8 riastrad RL(fd = open(FILE, O_CREAT|O_RDWR, 0644)); 175 1.8 riastrad RL(close(fd)); 176 1.8 riastrad 177 1.8 riastrad RL(dfd = open(getcwd(cwd, MAXPATHLEN), O_RDONLY, 0)); 178 1.8 riastrad ATF_CHECK_ERRNO(ENOENT, utimensat(dfd, BASEFILE, tptr, 0) == -1); 179 1.8 riastrad RL(close(dfd)); 180 1.1 manu } 181 1.1 manu 182 1.5 jmmv ATF_TC(utimensat_fderr3); 183 1.1 manu ATF_TC_HEAD(utimensat_fderr3, tc) 184 1.1 manu { 185 1.8 riastrad atf_tc_set_md_var(tc, "descr", 186 1.8 riastrad "See that utimensat fails with fd as -1"); 187 1.1 manu } 188 1.1 manu ATF_TC_BODY(utimensat_fderr3, tc) 189 1.1 manu { 190 1.1 manu int fd; 191 1.1 manu 192 1.8 riastrad RL(mkdir(DIR, 0755)); 193 1.8 riastrad RL(fd = open(FILE, O_CREAT|O_RDWR, 0644)); 194 1.8 riastrad RL(close(fd)); 195 1.1 manu 196 1.8 riastrad ATF_CHECK_ERRNO(EBADF, utimensat(-1, FILE, tptr, 0) == -1); 197 1.1 manu } 198 1.1 manu 199 1.5 jmmv ATF_TC(utimensat_fdlink); 200 1.1 manu ATF_TC_HEAD(utimensat_fdlink, tc) 201 1.1 manu { 202 1.1 manu atf_tc_set_md_var(tc, "descr", "See that utimensat works on symlink"); 203 1.1 manu } 204 1.1 manu ATF_TC_BODY(utimensat_fdlink, tc) 205 1.1 manu { 206 1.1 manu int dfd; 207 1.1 manu struct stat st; 208 1.9 riastrad struct statvfs fs; 209 1.1 manu 210 1.8 riastrad RL(mkdir(DIR, 0755)); 211 1.8 riastrad RL(symlink(FILE, LINK)); /* NB: FILE does not exists */ 212 1.1 manu 213 1.8 riastrad RL(dfd = open(DIR, O_RDONLY, 0)); 214 1.1 manu 215 1.8 riastrad ATF_CHECK_ERRNO(ENOENT, utimensat(dfd, BASELINK, tptr, 0) == -1); 216 1.1 manu 217 1.8 riastrad RL(utimensat(dfd, BASELINK, tptr, AT_SYMLINK_NOFOLLOW)); 218 1.1 manu 219 1.8 riastrad RL(close(dfd)); 220 1.1 manu 221 1.8 riastrad RL(lstat(LINK, &st)); 222 1.9 riastrad RL(statvfs(DIR, &fs)); /* XXX should do lstatvfs(LINK, &fs) */ 223 1.9 riastrad checkstattime(&st, &fs); 224 1.1 manu } 225 1.1 manu 226 1.1 manu ATF_TP_ADD_TCS(tp) 227 1.1 manu { 228 1.1 manu 229 1.1 manu ATF_TP_ADD_TC(tp, utimensat_fd); 230 1.1 manu ATF_TP_ADD_TC(tp, utimensat_fdcwd); 231 1.1 manu ATF_TP_ADD_TC(tp, utimensat_fdcwderr); 232 1.1 manu ATF_TP_ADD_TC(tp, utimensat_fderr1); 233 1.1 manu ATF_TP_ADD_TC(tp, utimensat_fderr2); 234 1.1 manu ATF_TP_ADD_TC(tp, utimensat_fderr3); 235 1.1 manu ATF_TP_ADD_TC(tp, utimensat_fdlink); 236 1.1 manu 237 1.1 manu return atf_no_error(); 238 1.1 manu } 239