xref: /netbsd-src/tests/lib/libc/c063/t_faccessat.c (revision 9844887ce7e6e11fc8f7b737fd37720103641e4a)
1*9844887cSchristos /*	$NetBSD: t_faccessat.c,v 1.5 2024/07/07 14:29:48 christos Exp $ */
2a76c1cc1Smanu 
3a76c1cc1Smanu /*-
4a76c1cc1Smanu  * Copyright (c) 2012 The NetBSD Foundation, Inc.
5a76c1cc1Smanu  * All rights reserved.
6a76c1cc1Smanu  *
7a76c1cc1Smanu  * This code is derived from software contributed to The NetBSD Foundation
8a76c1cc1Smanu  * by Emmanuel Dreyfus.
9a76c1cc1Smanu  *
10a76c1cc1Smanu  * Redistribution and use in source and binary forms, with or without
11a76c1cc1Smanu  * modification, are permitted provided that the following conditions
12a76c1cc1Smanu  * are met:
13a76c1cc1Smanu  * 1. Redistributions of source code must retain the above copyright
14a76c1cc1Smanu  *    notice, this list of conditions and the following disclaimer.
15a76c1cc1Smanu  * 2. Redistributions in binary form must reproduce the above copyright
16a76c1cc1Smanu  *    notice, this list of conditions and the following disclaimer in the
17a76c1cc1Smanu  *    documentation and/or other materials provided with the distribution.
18a76c1cc1Smanu  *
19a76c1cc1Smanu  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20a76c1cc1Smanu  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21a76c1cc1Smanu  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22a76c1cc1Smanu  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23a76c1cc1Smanu  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24a76c1cc1Smanu  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25a76c1cc1Smanu  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26a76c1cc1Smanu  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27a76c1cc1Smanu  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28a76c1cc1Smanu  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29a76c1cc1Smanu  * POSSIBILITY OF SUCH DAMAGE.
30a76c1cc1Smanu  */
31a76c1cc1Smanu #include <sys/cdefs.h>
32*9844887cSchristos __RCSID("$NetBSD: t_faccessat.c,v 1.5 2024/07/07 14:29:48 christos Exp $");
33a76c1cc1Smanu 
34e76b723bSchristos #include <sys/param.h>
35e76b723bSchristos #include <sys/stat.h>
36a76c1cc1Smanu #include <atf-c.h>
37a76c1cc1Smanu #include <errno.h>
38a76c1cc1Smanu #include <fcntl.h>
39a76c1cc1Smanu #include <limits.h>
40a76c1cc1Smanu #include <paths.h>
41a76c1cc1Smanu #include <stdio.h>
42a76c1cc1Smanu #include <string.h>
43a76c1cc1Smanu #include <unistd.h>
44a76c1cc1Smanu 
45a76c1cc1Smanu #define DIR "dir"
46a76c1cc1Smanu #define FILE "dir/faccessat"
47a76c1cc1Smanu #define BASEFILE "faccessat"
48a76c1cc1Smanu #define LINK "dir/symlink"
49a76c1cc1Smanu #define BASELINK "symlink"
50a76c1cc1Smanu #define FILEERR "dir/faccessaterr"
51a76c1cc1Smanu 
522be7ebf7Sjmmv ATF_TC(faccessat_fd);
ATF_TC_HEAD(faccessat_fd,tc)53a76c1cc1Smanu ATF_TC_HEAD(faccessat_fd, tc)
54a76c1cc1Smanu {
55a76c1cc1Smanu 	atf_tc_set_md_var(tc, "descr", "See that faccessat works with fd");
56a76c1cc1Smanu }
ATF_TC_BODY(faccessat_fd,tc)57a76c1cc1Smanu ATF_TC_BODY(faccessat_fd, tc)
58a76c1cc1Smanu {
59a76c1cc1Smanu 	int dfd;
60a76c1cc1Smanu 	int fd;
61a76c1cc1Smanu 
62a76c1cc1Smanu 	ATF_REQUIRE(mkdir(DIR, 0755) == 0);
63a76c1cc1Smanu 	ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1);
64a76c1cc1Smanu 	ATF_REQUIRE(close(fd) == 0);
65a76c1cc1Smanu 
66a76c1cc1Smanu 	ATF_REQUIRE((dfd = open(DIR, O_RDONLY, 0)) != -1);
67a76c1cc1Smanu 	ATF_REQUIRE(faccessat(dfd, BASEFILE, F_OK, 0) == 0);
68a76c1cc1Smanu 	ATF_REQUIRE(close(dfd) == 0);
69a76c1cc1Smanu }
70a76c1cc1Smanu 
712be7ebf7Sjmmv ATF_TC(faccessat_fdcwd);
ATF_TC_HEAD(faccessat_fdcwd,tc)72a76c1cc1Smanu ATF_TC_HEAD(faccessat_fdcwd, tc)
73a76c1cc1Smanu {
74a76c1cc1Smanu 	atf_tc_set_md_var(tc, "descr",
75a76c1cc1Smanu 	    "See that faccessat works with fd as AT_FDCWD");
76a76c1cc1Smanu }
ATF_TC_BODY(faccessat_fdcwd,tc)77a76c1cc1Smanu ATF_TC_BODY(faccessat_fdcwd, tc)
78a76c1cc1Smanu {
79a76c1cc1Smanu 	int fd;
80a76c1cc1Smanu 
81a76c1cc1Smanu 	ATF_REQUIRE(mkdir(DIR, 0755) == 0);
82a76c1cc1Smanu 	ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1);
83a76c1cc1Smanu 	ATF_REQUIRE(close(fd) == 0);
84a76c1cc1Smanu 
85a76c1cc1Smanu 	ATF_REQUIRE(chdir(DIR) == 0);
86a76c1cc1Smanu 	ATF_REQUIRE(faccessat(AT_FDCWD, BASEFILE, F_OK, 0) == 0);
87a76c1cc1Smanu }
88a76c1cc1Smanu 
892be7ebf7Sjmmv ATF_TC(faccessat_fdcwderr);
ATF_TC_HEAD(faccessat_fdcwderr,tc)90a76c1cc1Smanu ATF_TC_HEAD(faccessat_fdcwderr, tc)
91a76c1cc1Smanu {
92a76c1cc1Smanu 	atf_tc_set_md_var(tc, "descr",
93a76c1cc1Smanu 	    "See that faccessat fails with fd as AT_FDCWD and bad path");
94a76c1cc1Smanu }
ATF_TC_BODY(faccessat_fdcwderr,tc)95a76c1cc1Smanu ATF_TC_BODY(faccessat_fdcwderr, tc)
96a76c1cc1Smanu {
97a76c1cc1Smanu 	ATF_REQUIRE(mkdir(DIR, 0755) == 0);
98a76c1cc1Smanu 	ATF_REQUIRE(faccessat(AT_FDCWD, FILEERR, F_OK, 0) == -1);
99a76c1cc1Smanu }
100a76c1cc1Smanu 
1012be7ebf7Sjmmv ATF_TC(faccessat_fderr1);
ATF_TC_HEAD(faccessat_fderr1,tc)102a76c1cc1Smanu ATF_TC_HEAD(faccessat_fderr1, tc)
103a76c1cc1Smanu {
104a76c1cc1Smanu 	atf_tc_set_md_var(tc, "descr", "See that faccessat fail with bad path");
105a76c1cc1Smanu }
ATF_TC_BODY(faccessat_fderr1,tc)106a76c1cc1Smanu ATF_TC_BODY(faccessat_fderr1, tc)
107a76c1cc1Smanu {
108a76c1cc1Smanu 	int dfd;
109a76c1cc1Smanu 
110a76c1cc1Smanu 	ATF_REQUIRE(mkdir(DIR, 0755) == 0);
111a76c1cc1Smanu 	ATF_REQUIRE((dfd = open(DIR, O_RDONLY, 0)) != -1);
112a76c1cc1Smanu 	ATF_REQUIRE(faccessat(dfd, FILEERR, F_OK, 0) == -1);
113a76c1cc1Smanu 	ATF_REQUIRE(close(dfd) == 0);
114a76c1cc1Smanu }
115a76c1cc1Smanu 
1162be7ebf7Sjmmv ATF_TC(faccessat_fderr2);
ATF_TC_HEAD(faccessat_fderr2,tc)117a76c1cc1Smanu ATF_TC_HEAD(faccessat_fderr2, tc)
118a76c1cc1Smanu {
119a76c1cc1Smanu 	atf_tc_set_md_var(tc, "descr", "See that faccessat fails with bad fdat");
120a76c1cc1Smanu }
ATF_TC_BODY(faccessat_fderr2,tc)121a76c1cc1Smanu ATF_TC_BODY(faccessat_fderr2, tc)
122a76c1cc1Smanu {
123a76c1cc1Smanu 	int dfd;
124a76c1cc1Smanu 	int fd;
125a76c1cc1Smanu 	char cwd[MAXPATHLEN];
126a76c1cc1Smanu 
127a76c1cc1Smanu 	ATF_REQUIRE(mkdir(DIR, 0755) == 0);
128a76c1cc1Smanu 	ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1);
129a76c1cc1Smanu 	ATF_REQUIRE(close(fd) == 0);
130a76c1cc1Smanu 
131a76c1cc1Smanu 	ATF_REQUIRE((dfd = open(getcwd(cwd, MAXPATHLEN), O_RDONLY, 0)) != -1);
132a76c1cc1Smanu 	ATF_REQUIRE(faccessat(dfd, BASEFILE, F_OK, 0) == -1);
133a76c1cc1Smanu 	ATF_REQUIRE(close(dfd) == 0);
134a76c1cc1Smanu }
135a76c1cc1Smanu 
1362be7ebf7Sjmmv ATF_TC(faccessat_fderr3);
ATF_TC_HEAD(faccessat_fderr3,tc)137a76c1cc1Smanu ATF_TC_HEAD(faccessat_fderr3, tc)
138a76c1cc1Smanu {
139a76c1cc1Smanu 	atf_tc_set_md_var(tc, "descr", "See that faccessat fails with fd as -1");
140a76c1cc1Smanu }
ATF_TC_BODY(faccessat_fderr3,tc)141a76c1cc1Smanu ATF_TC_BODY(faccessat_fderr3, tc)
142a76c1cc1Smanu {
143a76c1cc1Smanu 	int fd;
144a76c1cc1Smanu 
145a76c1cc1Smanu 	ATF_REQUIRE(mkdir(DIR, 0755) == 0);
146a76c1cc1Smanu 	ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1);
147a76c1cc1Smanu 	ATF_REQUIRE(close(fd) == 0);
148a76c1cc1Smanu 
149a76c1cc1Smanu 	ATF_REQUIRE(faccessat(-1, FILE, F_OK, 0) == -1);
150a76c1cc1Smanu }
151a76c1cc1Smanu 
1522be7ebf7Sjmmv ATF_TC(faccessat_fdlink);
ATF_TC_HEAD(faccessat_fdlink,tc)153a76c1cc1Smanu ATF_TC_HEAD(faccessat_fdlink, tc)
154a76c1cc1Smanu {
155a76c1cc1Smanu 	atf_tc_set_md_var(tc, "descr", "See that faccessat works on symlink");
156a76c1cc1Smanu }
ATF_TC_BODY(faccessat_fdlink,tc)157a76c1cc1Smanu ATF_TC_BODY(faccessat_fdlink, tc)
158a76c1cc1Smanu {
159a76c1cc1Smanu 	int dfd;
160a76c1cc1Smanu 
161a76c1cc1Smanu 	ATF_REQUIRE(mkdir(DIR, 0755) == 0);
162a76c1cc1Smanu 	ATF_REQUIRE(symlink(FILE, LINK) == 0); /* NB: FILE does not exists */
163a76c1cc1Smanu 
164a76c1cc1Smanu 	ATF_REQUIRE((dfd = open(DIR, O_RDONLY, 0)) != -1);
165a76c1cc1Smanu 
166a76c1cc1Smanu 	ATF_REQUIRE(faccessat(dfd, BASELINK, F_OK, 0) == -1);
167a76c1cc1Smanu 	ATF_REQUIRE(errno == ENOENT);
168a76c1cc1Smanu 
169a76c1cc1Smanu 	ATF_REQUIRE(faccessat(dfd, BASELINK, F_OK, AT_SYMLINK_NOFOLLOW) == 0);
170a76c1cc1Smanu 
171a76c1cc1Smanu 	ATF_REQUIRE(close(dfd) == 0);
172a76c1cc1Smanu }
173a76c1cc1Smanu 
1740c467abdSchristos ATF_TC(faccessat_abs);
ATF_TC_HEAD(faccessat_abs,tc)1750c467abdSchristos ATF_TC_HEAD(faccessat_abs, tc)
1760c467abdSchristos {
1770c467abdSchristos 	atf_tc_set_md_var(tc, "descr", "See that faccessat works with invalid "
1780c467abdSchristos 	    "fd when absolute path is provided.");
1790c467abdSchristos }
ATF_TC_BODY(faccessat_abs,tc)1800c467abdSchristos ATF_TC_BODY(faccessat_abs, tc)
1810c467abdSchristos {
1820c467abdSchristos 	int fd;
1830c467abdSchristos 	char cwd[MAXPATHLEN];
184*9844887cSchristos 	char abs_path[MAXPATHLEN * 2];
1850c467abdSchristos 
1860c467abdSchristos 	ATF_REQUIRE(mkdir(DIR, 0755) == 0);
1870c467abdSchristos 	ATF_REQUIRE((fd = open(FILE, O_CREAT|O_RDWR, 0644)) != -1);
1880c467abdSchristos 	ATF_REQUIRE(close(fd) == 0);
1890c467abdSchristos 
1900c467abdSchristos 	ATF_REQUIRE(getcwd(cwd, MAXPATHLEN));
1910c467abdSchristos 	snprintf(abs_path, sizeof(abs_path), "%s/%s", cwd, FILE);
1920c467abdSchristos 	ATF_REQUIRE(faccessat(-1, abs_path, W_OK, 0) == 0);
1930c467abdSchristos 
1940c467abdSchristos }
1950c467abdSchristos 
1960c467abdSchristos ATF_TC(faccessat_abs_fddir);
ATF_TC_HEAD(faccessat_abs_fddir,tc)1970c467abdSchristos ATF_TC_HEAD(faccessat_abs_fddir, tc)
1980c467abdSchristos {
1990c467abdSchristos 	atf_tc_set_md_var(tc, "descr", "See that faccessat works with "
2000c467abdSchristos 	    "fd of directory when absolute path is provided.");
2010c467abdSchristos }
ATF_TC_BODY(faccessat_abs_fddir,tc)2020c467abdSchristos ATF_TC_BODY(faccessat_abs_fddir, tc)
2030c467abdSchristos {
2040c467abdSchristos 	int dfd;
2050c467abdSchristos 	char cwd[MAXPATHLEN];
206*9844887cSchristos 	char abs_path[MAXPATHLEN * 2];
2070c467abdSchristos 
2080c467abdSchristos 	ATF_REQUIRE(mkdir(DIR, 0755) == 0);
2090c467abdSchristos 	ATF_REQUIRE((dfd = open(DIR, O_RDONLY, 0)) != -1);
2100c467abdSchristos 	ATF_REQUIRE(close(dfd) == 0);
2110c467abdSchristos 
2120c467abdSchristos 	ATF_REQUIRE(getcwd(cwd, MAXPATHLEN));
2130c467abdSchristos 	snprintf(abs_path, sizeof(abs_path), "%s/%s", cwd, DIR);
2140c467abdSchristos 	ATF_REQUIRE(faccessat(dfd, abs_path, W_OK, 0) == 0);
2150c467abdSchristos 
2160c467abdSchristos }
2170c467abdSchristos 
2180c467abdSchristos ATF_TC(faccessat_abs_fdcwd);
ATF_TC_HEAD(faccessat_abs_fdcwd,tc)2190c467abdSchristos ATF_TC_HEAD(faccessat_abs_fdcwd, tc)
2200c467abdSchristos {
2210c467abdSchristos 	atf_tc_set_md_var(tc, "descr", "See that faccessat works with fd "
2220c467abdSchristos 	    "of current directory when absolute path is provided.");
2230c467abdSchristos }
ATF_TC_BODY(faccessat_abs_fdcwd,tc)2240c467abdSchristos ATF_TC_BODY(faccessat_abs_fdcwd, tc)
2250c467abdSchristos {
2260c467abdSchristos 	char cwd[MAXPATHLEN];
227*9844887cSchristos 	char abs_path[MAXPATHLEN * 2];
2280c467abdSchristos 
2290c467abdSchristos 	ATF_REQUIRE(mkdir(DIR, 0755) == 0);
2300c467abdSchristos 
2310c467abdSchristos 	ATF_REQUIRE(getcwd(cwd, MAXPATHLEN));
2320c467abdSchristos 	snprintf(abs_path, sizeof(abs_path), "%s/%s", cwd, DIR);
2330c467abdSchristos 	ATF_REQUIRE(faccessat(AT_FDCWD, abs_path, W_OK, 0) == 0);
2340c467abdSchristos }
2350c467abdSchristos 
ATF_TP_ADD_TCS(tp)236a76c1cc1Smanu ATF_TP_ADD_TCS(tp)
237a76c1cc1Smanu {
238a76c1cc1Smanu 
239a76c1cc1Smanu 	ATF_TP_ADD_TC(tp, faccessat_fd);
240a76c1cc1Smanu 	ATF_TP_ADD_TC(tp, faccessat_fdcwd);
241a76c1cc1Smanu 	ATF_TP_ADD_TC(tp, faccessat_fdcwderr);
242a76c1cc1Smanu 	ATF_TP_ADD_TC(tp, faccessat_fderr1);
243a76c1cc1Smanu 	ATF_TP_ADD_TC(tp, faccessat_fderr2);
244a76c1cc1Smanu 	ATF_TP_ADD_TC(tp, faccessat_fderr3);
245a76c1cc1Smanu 	ATF_TP_ADD_TC(tp, faccessat_fdlink);
2460c467abdSchristos 	ATF_TP_ADD_TC(tp, faccessat_abs);
2470c467abdSchristos 	ATF_TP_ADD_TC(tp, faccessat_abs_fddir);
2480c467abdSchristos 	ATF_TP_ADD_TC(tp, faccessat_abs_fdcwd);
249a76c1cc1Smanu 
250a76c1cc1Smanu 	return atf_no_error();
251a76c1cc1Smanu }
252