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