xref: /freebsd/lib/libc/tests/gen/scandir_blocks_test.c (revision 0a5b763d98b921f921243525ff25a70bbe00cfaa)
1deeebfdeSDag-Erling Smørgrav /*-
2deeebfdeSDag-Erling Smørgrav  * Copyright (c) 2025 Klara, Inc.
3deeebfdeSDag-Erling Smørgrav  *
4deeebfdeSDag-Erling Smørgrav  * SPDX-License-Identifier: BSD-2-Clause
5deeebfdeSDag-Erling Smørgrav  */
6deeebfdeSDag-Erling Smørgrav 
7deeebfdeSDag-Erling Smørgrav #include <sys/stat.h>
8deeebfdeSDag-Erling Smørgrav 
9deeebfdeSDag-Erling Smørgrav #include <dirent.h>
10deeebfdeSDag-Erling Smørgrav #include <fcntl.h>
11deeebfdeSDag-Erling Smørgrav #include <stdlib.h>
12deeebfdeSDag-Erling Smørgrav 
13deeebfdeSDag-Erling Smørgrav #include <atf-c.h>
14deeebfdeSDag-Erling Smørgrav 
15deeebfdeSDag-Erling Smørgrav static void
scandir_blocks_prepare(const struct atf_tc * tc)16deeebfdeSDag-Erling Smørgrav scandir_blocks_prepare(const struct atf_tc *tc)
17deeebfdeSDag-Erling Smørgrav {
18deeebfdeSDag-Erling Smørgrav 	ATF_REQUIRE_EQ(0, mkdir("dir", 0755));
19deeebfdeSDag-Erling Smørgrav 	ATF_REQUIRE_EQ(0, mkdir("dir/dir", 0755));
20deeebfdeSDag-Erling Smørgrav 	ATF_REQUIRE_EQ(0, close(creat("dir/file", 0644)));
21deeebfdeSDag-Erling Smørgrav 	ATF_REQUIRE_EQ(0, symlink("file", "dir/link"));
22deeebfdeSDag-Erling Smørgrav 	ATF_REQUIRE_EQ(0, mkdir("dir/skip", 0755));
23deeebfdeSDag-Erling Smørgrav }
24deeebfdeSDag-Erling Smørgrav 
25deeebfdeSDag-Erling Smørgrav static void
scandir_blocks_verify(const struct atf_tc * tc,int n,struct dirent ** namelist)26deeebfdeSDag-Erling Smørgrav scandir_blocks_verify(const struct atf_tc *tc, int n, struct dirent **namelist)
27deeebfdeSDag-Erling Smørgrav {
28deeebfdeSDag-Erling Smørgrav 	ATF_REQUIRE_EQ_MSG(5, n, "return value is %d", n);
29deeebfdeSDag-Erling Smørgrav 	ATF_CHECK_STREQ("link", namelist[0]->d_name);
30deeebfdeSDag-Erling Smørgrav 	ATF_CHECK_STREQ("file", namelist[1]->d_name);
31deeebfdeSDag-Erling Smørgrav 	ATF_CHECK_STREQ("dir", namelist[2]->d_name);
32deeebfdeSDag-Erling Smørgrav 	ATF_CHECK_STREQ("..", namelist[3]->d_name);
33deeebfdeSDag-Erling Smørgrav 	ATF_CHECK_STREQ(".", namelist[4]->d_name);
34deeebfdeSDag-Erling Smørgrav }
35deeebfdeSDag-Erling Smørgrav 
36deeebfdeSDag-Erling Smørgrav ATF_TC(scandir_b_test);
ATF_TC_HEAD(scandir_b_test,tc)37deeebfdeSDag-Erling Smørgrav ATF_TC_HEAD(scandir_b_test, tc)
38deeebfdeSDag-Erling Smørgrav {
39deeebfdeSDag-Erling Smørgrav 	atf_tc_set_md_var(tc, "descr", "Test scandir_b()");
40deeebfdeSDag-Erling Smørgrav }
ATF_TC_BODY(scandir_b_test,tc)41deeebfdeSDag-Erling Smørgrav ATF_TC_BODY(scandir_b_test, tc)
42deeebfdeSDag-Erling Smørgrav {
43deeebfdeSDag-Erling Smørgrav 	struct dirent **namelist = NULL;
44deeebfdeSDag-Erling Smørgrav 	int i, ret;
45deeebfdeSDag-Erling Smørgrav 
46deeebfdeSDag-Erling Smørgrav 	scandir_blocks_prepare(tc);
47deeebfdeSDag-Erling Smørgrav 	ret = scandir_b("dir", &namelist,
48deeebfdeSDag-Erling Smørgrav 	    ^(const struct dirent *ent) {
49deeebfdeSDag-Erling Smørgrav 		    return (strcmp(ent->d_name, "skip") != 0);
50deeebfdeSDag-Erling Smørgrav 	    },
51deeebfdeSDag-Erling Smørgrav 	    ^(const struct dirent **a, const struct dirent **b) {
52deeebfdeSDag-Erling Smørgrav 		    return (strcmp((*b)->d_name, (*a)->d_name));
53deeebfdeSDag-Erling Smørgrav 	    });
54deeebfdeSDag-Erling Smørgrav 	scandir_blocks_verify(tc, ret, namelist);
55deeebfdeSDag-Erling Smørgrav 	for (i = 0; i < ret; i++)
56deeebfdeSDag-Erling Smørgrav 		free(namelist[i]);
57deeebfdeSDag-Erling Smørgrav 	free(namelist);
58deeebfdeSDag-Erling Smørgrav }
59deeebfdeSDag-Erling Smørgrav 
60*0a5b763dSDag-Erling Smørgrav ATF_TC(fdscandir_b_test);
ATF_TC_HEAD(fdscandir_b_test,tc)61*0a5b763dSDag-Erling Smørgrav ATF_TC_HEAD(fdscandir_b_test, tc)
62deeebfdeSDag-Erling Smørgrav {
63*0a5b763dSDag-Erling Smørgrav 	atf_tc_set_md_var(tc, "descr", "Test fdscandir_b()");
64deeebfdeSDag-Erling Smørgrav }
ATF_TC_BODY(fdscandir_b_test,tc)65*0a5b763dSDag-Erling Smørgrav ATF_TC_BODY(fdscandir_b_test, tc)
66deeebfdeSDag-Erling Smørgrav {
67deeebfdeSDag-Erling Smørgrav 	struct dirent **namelist = NULL;
68deeebfdeSDag-Erling Smørgrav 	int fd, i, ret;
69deeebfdeSDag-Erling Smørgrav 
70deeebfdeSDag-Erling Smørgrav 	scandir_blocks_prepare(tc);
71deeebfdeSDag-Erling Smørgrav 	ATF_REQUIRE((fd = open("dir", O_DIRECTORY | O_RDONLY)) >= 0);
72*0a5b763dSDag-Erling Smørgrav 	ret = fdscandir_b(fd, &namelist,
73deeebfdeSDag-Erling Smørgrav 	    ^(const struct dirent *ent) {
74deeebfdeSDag-Erling Smørgrav 		    return (strcmp(ent->d_name, "skip") != 0);
75deeebfdeSDag-Erling Smørgrav 	    },
76deeebfdeSDag-Erling Smørgrav 	    ^(const struct dirent **a, const struct dirent **b) {
77deeebfdeSDag-Erling Smørgrav 		    return (strcmp((*b)->d_name, (*a)->d_name));
78deeebfdeSDag-Erling Smørgrav 	    });
79deeebfdeSDag-Erling Smørgrav 	scandir_blocks_verify(tc, ret, namelist);
80deeebfdeSDag-Erling Smørgrav 	for (i = 0; i < ret; i++)
81deeebfdeSDag-Erling Smørgrav 		free(namelist[i]);
82deeebfdeSDag-Erling Smørgrav 	free(namelist);
83deeebfdeSDag-Erling Smørgrav 	ATF_REQUIRE_EQ(0, close(fd));
84deeebfdeSDag-Erling Smørgrav }
85deeebfdeSDag-Erling Smørgrav 
86deeebfdeSDag-Erling Smørgrav ATF_TC(scandirat_b_test);
ATF_TC_HEAD(scandirat_b_test,tc)87deeebfdeSDag-Erling Smørgrav ATF_TC_HEAD(scandirat_b_test, tc)
88deeebfdeSDag-Erling Smørgrav {
89deeebfdeSDag-Erling Smørgrav 	atf_tc_set_md_var(tc, "descr", "Test scandirat_b()");
90deeebfdeSDag-Erling Smørgrav }
ATF_TC_BODY(scandirat_b_test,tc)91deeebfdeSDag-Erling Smørgrav ATF_TC_BODY(scandirat_b_test, tc)
92deeebfdeSDag-Erling Smørgrav {
93deeebfdeSDag-Erling Smørgrav 	struct dirent **namelist = NULL;
94deeebfdeSDag-Erling Smørgrav 	int fd, i, ret;
95deeebfdeSDag-Erling Smørgrav 
96deeebfdeSDag-Erling Smørgrav 	scandir_blocks_prepare(tc);
97deeebfdeSDag-Erling Smørgrav 	ATF_REQUIRE((fd = open("dir", O_DIRECTORY | O_SEARCH)) >= 0);
98deeebfdeSDag-Erling Smørgrav 	ret = scandirat_b(fd, ".", &namelist,
99deeebfdeSDag-Erling Smørgrav 	    ^(const struct dirent *ent) {
100deeebfdeSDag-Erling Smørgrav 		    return (strcmp(ent->d_name, "skip") != 0);
101deeebfdeSDag-Erling Smørgrav 	    },
102deeebfdeSDag-Erling Smørgrav 	    ^(const struct dirent **a, const struct dirent **b) {
103deeebfdeSDag-Erling Smørgrav 		    return (strcmp((*b)->d_name, (*a)->d_name));
104deeebfdeSDag-Erling Smørgrav 	    });
105deeebfdeSDag-Erling Smørgrav 	scandir_blocks_verify(tc, ret, namelist);
106deeebfdeSDag-Erling Smørgrav 	for (i = 0; i < ret; i++)
107deeebfdeSDag-Erling Smørgrav 		free(namelist[i]);
108deeebfdeSDag-Erling Smørgrav 	free(namelist);
109deeebfdeSDag-Erling Smørgrav 	ATF_REQUIRE_EQ(0, close(fd));
110deeebfdeSDag-Erling Smørgrav }
111deeebfdeSDag-Erling Smørgrav 
ATF_TP_ADD_TCS(tp)112deeebfdeSDag-Erling Smørgrav ATF_TP_ADD_TCS(tp)
113deeebfdeSDag-Erling Smørgrav {
114deeebfdeSDag-Erling Smørgrav 	ATF_TP_ADD_TC(tp, scandir_b_test);
115*0a5b763dSDag-Erling Smørgrav 	ATF_TP_ADD_TC(tp, fdscandir_b_test);
116deeebfdeSDag-Erling Smørgrav 	ATF_TP_ADD_TC(tp, scandirat_b_test);
117deeebfdeSDag-Erling Smørgrav 	return (atf_no_error());
118deeebfdeSDag-Erling Smørgrav }
119