1*d30a84abSDag-Erling Smørgrav /*-
2*d30a84abSDag-Erling Smørgrav * Copyright (c) 2025 Klara, Inc.
3*d30a84abSDag-Erling Smørgrav *
4*d30a84abSDag-Erling Smørgrav * SPDX-License-Identifier: BSD-2-Clause
5*d30a84abSDag-Erling Smørgrav */
6*d30a84abSDag-Erling Smørgrav
7*d30a84abSDag-Erling Smørgrav #include <sys/stat.h>
8*d30a84abSDag-Erling Smørgrav
9*d30a84abSDag-Erling Smørgrav #include <fcntl.h>
10*d30a84abSDag-Erling Smørgrav #include <fts.h>
11*d30a84abSDag-Erling Smørgrav #include <stdbool.h>
12*d30a84abSDag-Erling Smørgrav #include <stdio.h>
13*d30a84abSDag-Erling Smørgrav #include <stdlib.h>
14*d30a84abSDag-Erling Smørgrav #include <unistd.h>
15*d30a84abSDag-Erling Smørgrav
16*d30a84abSDag-Erling Smørgrav #include <atf-c.h>
17*d30a84abSDag-Erling Smørgrav
18*d30a84abSDag-Erling Smørgrav struct fts_expect {
19*d30a84abSDag-Erling Smørgrav int fts_info;
20*d30a84abSDag-Erling Smørgrav const char *fts_name;
21*d30a84abSDag-Erling Smørgrav const char *fts_accpath;
22*d30a84abSDag-Erling Smørgrav };
23*d30a84abSDag-Erling Smørgrav
24*d30a84abSDag-Erling Smørgrav struct fts_testcase {
25*d30a84abSDag-Erling Smørgrav char **paths;
26*d30a84abSDag-Erling Smørgrav int fts_options;
27*d30a84abSDag-Erling Smørgrav struct fts_expect *fts_expect;
28*d30a84abSDag-Erling Smørgrav };
29*d30a84abSDag-Erling Smørgrav
30*d30a84abSDag-Erling Smørgrav static char *all_paths[] = {
31*d30a84abSDag-Erling Smørgrav "dir",
32*d30a84abSDag-Erling Smørgrav "dirl",
33*d30a84abSDag-Erling Smørgrav "file",
34*d30a84abSDag-Erling Smørgrav "filel",
35*d30a84abSDag-Erling Smørgrav "dead",
36*d30a84abSDag-Erling Smørgrav "noent",
37*d30a84abSDag-Erling Smørgrav NULL
38*d30a84abSDag-Erling Smørgrav };
39*d30a84abSDag-Erling Smørgrav
40*d30a84abSDag-Erling Smørgrav /* shorter name for dead links */
41*d30a84abSDag-Erling Smørgrav #define FTS_DL FTS_SLNONE
42*d30a84abSDag-Erling Smørgrav
43*d30a84abSDag-Erling Smørgrav /* are we being debugged? */
44*d30a84abSDag-Erling Smørgrav static bool debug;
45*d30a84abSDag-Erling Smørgrav
46*d30a84abSDag-Erling Smørgrav /*
47*d30a84abSDag-Erling Smørgrav * Prepare the files and directories we will be inspecting.
48*d30a84abSDag-Erling Smørgrav */
49*d30a84abSDag-Erling Smørgrav static void
fts_options_prepare(const struct atf_tc * tc)50*d30a84abSDag-Erling Smørgrav fts_options_prepare(const struct atf_tc *tc)
51*d30a84abSDag-Erling Smørgrav {
52*d30a84abSDag-Erling Smørgrav debug = !getenv("__RUNNING_INSIDE_ATF_RUN") &&
53*d30a84abSDag-Erling Smørgrav isatty(STDERR_FILENO);
54*d30a84abSDag-Erling Smørgrav ATF_REQUIRE_EQ(0, mkdir("dir", 0755));
55*d30a84abSDag-Erling Smørgrav ATF_REQUIRE_EQ(0, close(creat("file", 0644)));
56*d30a84abSDag-Erling Smørgrav ATF_REQUIRE_EQ(0, close(creat("dir/file", 0644)));
57*d30a84abSDag-Erling Smørgrav ATF_REQUIRE_EQ(0, symlink("..", "dir/up"));
58*d30a84abSDag-Erling Smørgrav ATF_REQUIRE_EQ(0, symlink("dir", "dirl"));
59*d30a84abSDag-Erling Smørgrav ATF_REQUIRE_EQ(0, symlink("file", "filel"));
60*d30a84abSDag-Erling Smørgrav ATF_REQUIRE_EQ(0, symlink("noent", "dead"));
61*d30a84abSDag-Erling Smørgrav }
62*d30a84abSDag-Erling Smørgrav
63*d30a84abSDag-Erling Smørgrav /*
64*d30a84abSDag-Erling Smørgrav * Lexical order for reproducability.
65*d30a84abSDag-Erling Smørgrav */
66*d30a84abSDag-Erling Smørgrav static int
fts_options_compar(const FTSENT * const * a,const FTSENT * const * b)67*d30a84abSDag-Erling Smørgrav fts_options_compar(const FTSENT * const *a, const FTSENT * const *b)
68*d30a84abSDag-Erling Smørgrav {
69*d30a84abSDag-Erling Smørgrav return (strcmp((*a)->fts_name, (*b)->fts_name));
70*d30a84abSDag-Erling Smørgrav }
71*d30a84abSDag-Erling Smørgrav
72*d30a84abSDag-Erling Smørgrav /*
73*d30a84abSDag-Erling Smørgrav * Run FTS with the specified paths and options and verify that it
74*d30a84abSDag-Erling Smørgrav * produces the expected result in the correct order.
75*d30a84abSDag-Erling Smørgrav */
76*d30a84abSDag-Erling Smørgrav static void
fts_options_test(const struct atf_tc * tc,const struct fts_testcase * fts_tc)77*d30a84abSDag-Erling Smørgrav fts_options_test(const struct atf_tc *tc, const struct fts_testcase *fts_tc)
78*d30a84abSDag-Erling Smørgrav {
79*d30a84abSDag-Erling Smørgrav FTS *fts;
80*d30a84abSDag-Erling Smørgrav FTSENT *ftse;
81*d30a84abSDag-Erling Smørgrav const struct fts_expect *expect = fts_tc->fts_expect;
82*d30a84abSDag-Erling Smørgrav long level = 0;
83*d30a84abSDag-Erling Smørgrav
84*d30a84abSDag-Erling Smørgrav fts = fts_open(fts_tc->paths, fts_tc->fts_options, fts_options_compar);
85*d30a84abSDag-Erling Smørgrav ATF_REQUIRE_MSG(fts != NULL, "fts_open(): %m");
86*d30a84abSDag-Erling Smørgrav while ((ftse = fts_read(fts)) != NULL && expect->fts_name != NULL) {
87*d30a84abSDag-Erling Smørgrav if (expect->fts_info == FTS_DP)
88*d30a84abSDag-Erling Smørgrav level--;
89*d30a84abSDag-Erling Smørgrav if (debug) {
90*d30a84abSDag-Erling Smørgrav fprintf(stderr, "%2ld %2d %s\n", level,
91*d30a84abSDag-Erling Smørgrav ftse->fts_info, ftse->fts_name);
92*d30a84abSDag-Erling Smørgrav }
93*d30a84abSDag-Erling Smørgrav ATF_CHECK_STREQ(expect->fts_name, ftse->fts_name);
94*d30a84abSDag-Erling Smørgrav ATF_CHECK_STREQ(expect->fts_accpath, ftse->fts_accpath);
95*d30a84abSDag-Erling Smørgrav ATF_CHECK_INTEQ(expect->fts_info, ftse->fts_info);
96*d30a84abSDag-Erling Smørgrav ATF_CHECK_INTEQ(level, ftse->fts_level);
97*d30a84abSDag-Erling Smørgrav if (expect->fts_info == FTS_D)
98*d30a84abSDag-Erling Smørgrav level++;
99*d30a84abSDag-Erling Smørgrav expect++;
100*d30a84abSDag-Erling Smørgrav }
101*d30a84abSDag-Erling Smørgrav ATF_CHECK_EQ(NULL, ftse);
102*d30a84abSDag-Erling Smørgrav ATF_CHECK_EQ(NULL, expect->fts_name);
103*d30a84abSDag-Erling Smørgrav ATF_REQUIRE_EQ_MSG(0, fts_close(fts), "fts_close(): %m");
104*d30a84abSDag-Erling Smørgrav }
105*d30a84abSDag-Erling Smørgrav
106*d30a84abSDag-Erling Smørgrav ATF_TC(fts_options_logical);
ATF_TC_HEAD(fts_options_logical,tc)107*d30a84abSDag-Erling Smørgrav ATF_TC_HEAD(fts_options_logical, tc)
108*d30a84abSDag-Erling Smørgrav {
109*d30a84abSDag-Erling Smørgrav atf_tc_set_md_var(tc, "descr", "FTS_LOGICAL");
110*d30a84abSDag-Erling Smørgrav }
ATF_TC_BODY(fts_options_logical,tc)111*d30a84abSDag-Erling Smørgrav ATF_TC_BODY(fts_options_logical, tc)
112*d30a84abSDag-Erling Smørgrav {
113*d30a84abSDag-Erling Smørgrav fts_options_prepare(tc);
114*d30a84abSDag-Erling Smørgrav fts_options_test(tc, &(struct fts_testcase){
115*d30a84abSDag-Erling Smørgrav all_paths,
116*d30a84abSDag-Erling Smørgrav FTS_LOGICAL,
117*d30a84abSDag-Erling Smørgrav (struct fts_expect[]){
118*d30a84abSDag-Erling Smørgrav { FTS_DL, "dead", "dead" },
119*d30a84abSDag-Erling Smørgrav { FTS_D, "dir", "dir" },
120*d30a84abSDag-Erling Smørgrav { FTS_F, "file", "dir/file" },
121*d30a84abSDag-Erling Smørgrav { FTS_D, "up", "dir/up" },
122*d30a84abSDag-Erling Smørgrav { FTS_DL, "dead", "dir/up/dead" },
123*d30a84abSDag-Erling Smørgrav { FTS_DC, "dir", "dir/up/dir" },
124*d30a84abSDag-Erling Smørgrav { FTS_DC, "dirl", "dir/up/dirl" },
125*d30a84abSDag-Erling Smørgrav { FTS_F, "file", "dir/up/file" },
126*d30a84abSDag-Erling Smørgrav { FTS_F, "filel", "dir/up/filel" },
127*d30a84abSDag-Erling Smørgrav { FTS_DP, "up", "dir/up" },
128*d30a84abSDag-Erling Smørgrav { FTS_DP, "dir", "dir" },
129*d30a84abSDag-Erling Smørgrav { FTS_D, "dirl", "dirl" },
130*d30a84abSDag-Erling Smørgrav { FTS_F, "file", "dirl/file" },
131*d30a84abSDag-Erling Smørgrav { FTS_D, "up", "dirl/up" },
132*d30a84abSDag-Erling Smørgrav { FTS_DL, "dead", "dirl/up/dead" },
133*d30a84abSDag-Erling Smørgrav { FTS_DC, "dir", "dirl/up/dir" },
134*d30a84abSDag-Erling Smørgrav { FTS_DC, "dirl", "dirl/up/dirl" },
135*d30a84abSDag-Erling Smørgrav { FTS_F, "file", "dirl/up/file" },
136*d30a84abSDag-Erling Smørgrav { FTS_F, "filel", "dirl/up/filel" },
137*d30a84abSDag-Erling Smørgrav { FTS_DP, "up", "dirl/up" },
138*d30a84abSDag-Erling Smørgrav { FTS_DP, "dirl", "dirl" },
139*d30a84abSDag-Erling Smørgrav { FTS_F, "file", "file" },
140*d30a84abSDag-Erling Smørgrav { FTS_F, "filel", "filel" },
141*d30a84abSDag-Erling Smørgrav { FTS_NS, "noent", "noent" },
142*d30a84abSDag-Erling Smørgrav { 0 }
143*d30a84abSDag-Erling Smørgrav },
144*d30a84abSDag-Erling Smørgrav });
145*d30a84abSDag-Erling Smørgrav }
146*d30a84abSDag-Erling Smørgrav
147*d30a84abSDag-Erling Smørgrav ATF_TC(fts_options_logical_nostat);
ATF_TC_HEAD(fts_options_logical_nostat,tc)148*d30a84abSDag-Erling Smørgrav ATF_TC_HEAD(fts_options_logical_nostat, tc)
149*d30a84abSDag-Erling Smørgrav {
150*d30a84abSDag-Erling Smørgrav atf_tc_set_md_var(tc, "descr", "FTS_LOGICAL | FTS_NOSTAT");
151*d30a84abSDag-Erling Smørgrav }
ATF_TC_BODY(fts_options_logical_nostat,tc)152*d30a84abSDag-Erling Smørgrav ATF_TC_BODY(fts_options_logical_nostat, tc)
153*d30a84abSDag-Erling Smørgrav {
154*d30a84abSDag-Erling Smørgrav /*
155*d30a84abSDag-Erling Smørgrav * While FTS_LOGICAL is not documented as being incompatible with
156*d30a84abSDag-Erling Smørgrav * FTS_NOSTAT, and FTS does not clear FTS_NOSTAT if FTS_LOGICAL is
157*d30a84abSDag-Erling Smørgrav * set, FTS_LOGICAL effectively nullifies FTS_NOSTAT by overriding
158*d30a84abSDag-Erling Smørgrav * the follow check in fts_stat(). In theory, FTS could easily be
159*d30a84abSDag-Erling Smørgrav * changed to only stat links (to check what they point to) in the
160*d30a84abSDag-Erling Smørgrav * FTS_LOGICAL | FTS_NOSTAT case, which would produce a different
161*d30a84abSDag-Erling Smørgrav * result here, so keep the test around in case that ever happens.
162*d30a84abSDag-Erling Smørgrav */
163*d30a84abSDag-Erling Smørgrav atf_tc_expect_fail("FTS_LOGICAL nullifies FTS_NOSTAT");
164*d30a84abSDag-Erling Smørgrav fts_options_prepare(tc);
165*d30a84abSDag-Erling Smørgrav fts_options_test(tc, &(struct fts_testcase){
166*d30a84abSDag-Erling Smørgrav all_paths,
167*d30a84abSDag-Erling Smørgrav FTS_LOGICAL | FTS_NOSTAT,
168*d30a84abSDag-Erling Smørgrav (struct fts_expect[]){
169*d30a84abSDag-Erling Smørgrav { FTS_DL, "dead", "dead" },
170*d30a84abSDag-Erling Smørgrav { FTS_D, "dir", "dir" },
171*d30a84abSDag-Erling Smørgrav { FTS_NSOK, "file", "dir/file" },
172*d30a84abSDag-Erling Smørgrav { FTS_D, "up", "dir/up" },
173*d30a84abSDag-Erling Smørgrav { FTS_DL, "dead", "dir/up/dead" },
174*d30a84abSDag-Erling Smørgrav { FTS_DC, "dir", "dir/up/dir" },
175*d30a84abSDag-Erling Smørgrav { FTS_DC, "dirl", "dir/up/dirl" },
176*d30a84abSDag-Erling Smørgrav { FTS_NSOK, "file", "dir/up/file" },
177*d30a84abSDag-Erling Smørgrav { FTS_NSOK, "filel", "dir/up/filel" },
178*d30a84abSDag-Erling Smørgrav { FTS_DP, "up", "dir/up" },
179*d30a84abSDag-Erling Smørgrav { FTS_DP, "dir", "dir" },
180*d30a84abSDag-Erling Smørgrav { FTS_D, "dirl", "dirl" },
181*d30a84abSDag-Erling Smørgrav { FTS_NSOK, "file", "dirl/file" },
182*d30a84abSDag-Erling Smørgrav { FTS_D, "up", "dirl/up" },
183*d30a84abSDag-Erling Smørgrav { FTS_DL, "dead", "dirl/up/dead" },
184*d30a84abSDag-Erling Smørgrav { FTS_DC, "dir", "dirl/up/dir" },
185*d30a84abSDag-Erling Smørgrav { FTS_DC, "dirl", "dirl/up/dirl" },
186*d30a84abSDag-Erling Smørgrav { FTS_NSOK, "file", "dirl/up/file" },
187*d30a84abSDag-Erling Smørgrav { FTS_NSOK, "filel", "dirl/up/filel" },
188*d30a84abSDag-Erling Smørgrav { FTS_DP, "up", "dirl/up" },
189*d30a84abSDag-Erling Smørgrav { FTS_DP, "dirl", "dirl" },
190*d30a84abSDag-Erling Smørgrav { FTS_F, "file", "file" },
191*d30a84abSDag-Erling Smørgrav { FTS_F, "filel", "filel" },
192*d30a84abSDag-Erling Smørgrav { FTS_NS, "noent", "noent" },
193*d30a84abSDag-Erling Smørgrav { 0 }
194*d30a84abSDag-Erling Smørgrav },
195*d30a84abSDag-Erling Smørgrav });
196*d30a84abSDag-Erling Smørgrav }
197*d30a84abSDag-Erling Smørgrav
198*d30a84abSDag-Erling Smørgrav ATF_TC(fts_options_logical_seedot);
ATF_TC_HEAD(fts_options_logical_seedot,tc)199*d30a84abSDag-Erling Smørgrav ATF_TC_HEAD(fts_options_logical_seedot, tc)
200*d30a84abSDag-Erling Smørgrav {
201*d30a84abSDag-Erling Smørgrav atf_tc_set_md_var(tc, "descr", "FTS_LOGICAL | FTS_SEEDOT");
202*d30a84abSDag-Erling Smørgrav }
ATF_TC_BODY(fts_options_logical_seedot,tc)203*d30a84abSDag-Erling Smørgrav ATF_TC_BODY(fts_options_logical_seedot, tc)
204*d30a84abSDag-Erling Smørgrav {
205*d30a84abSDag-Erling Smørgrav fts_options_prepare(tc);
206*d30a84abSDag-Erling Smørgrav fts_options_test(tc, &(struct fts_testcase){
207*d30a84abSDag-Erling Smørgrav all_paths,
208*d30a84abSDag-Erling Smørgrav FTS_LOGICAL | FTS_SEEDOT,
209*d30a84abSDag-Erling Smørgrav (struct fts_expect[]){
210*d30a84abSDag-Erling Smørgrav { FTS_DL, "dead", "dead" },
211*d30a84abSDag-Erling Smørgrav { FTS_D, "dir", "dir" },
212*d30a84abSDag-Erling Smørgrav { FTS_DOT, ".", "dir/." },
213*d30a84abSDag-Erling Smørgrav { FTS_DOT, "..", "dir/.." },
214*d30a84abSDag-Erling Smørgrav { FTS_F, "file", "dir/file" },
215*d30a84abSDag-Erling Smørgrav { FTS_D, "up", "dir/up" },
216*d30a84abSDag-Erling Smørgrav { FTS_DOT, ".", "dir/up/." },
217*d30a84abSDag-Erling Smørgrav { FTS_DOT, "..", "dir/up/.." },
218*d30a84abSDag-Erling Smørgrav { FTS_DL, "dead", "dir/up/dead" },
219*d30a84abSDag-Erling Smørgrav { FTS_DC, "dir", "dir/up/dir" },
220*d30a84abSDag-Erling Smørgrav { FTS_DC, "dirl", "dir/up/dirl" },
221*d30a84abSDag-Erling Smørgrav { FTS_F, "file", "dir/up/file" },
222*d30a84abSDag-Erling Smørgrav { FTS_F, "filel", "dir/up/filel" },
223*d30a84abSDag-Erling Smørgrav { FTS_DP, "up", "dir/up" },
224*d30a84abSDag-Erling Smørgrav { FTS_DP, "dir", "dir" },
225*d30a84abSDag-Erling Smørgrav { FTS_D, "dirl", "dirl" },
226*d30a84abSDag-Erling Smørgrav { FTS_DOT, ".", "dirl/." },
227*d30a84abSDag-Erling Smørgrav { FTS_DOT, "..", "dirl/.." },
228*d30a84abSDag-Erling Smørgrav { FTS_F, "file", "dirl/file" },
229*d30a84abSDag-Erling Smørgrav { FTS_D, "up", "dirl/up" },
230*d30a84abSDag-Erling Smørgrav { FTS_DOT, ".", "dirl/up/." },
231*d30a84abSDag-Erling Smørgrav { FTS_DOT, "..", "dirl/up/.." },
232*d30a84abSDag-Erling Smørgrav { FTS_DL, "dead", "dirl/up/dead" },
233*d30a84abSDag-Erling Smørgrav { FTS_DC, "dir", "dirl/up/dir" },
234*d30a84abSDag-Erling Smørgrav { FTS_DC, "dirl", "dirl/up/dirl" },
235*d30a84abSDag-Erling Smørgrav { FTS_F, "file", "dirl/up/file" },
236*d30a84abSDag-Erling Smørgrav { FTS_F, "filel", "dirl/up/filel" },
237*d30a84abSDag-Erling Smørgrav { FTS_DP, "up", "dirl/up" },
238*d30a84abSDag-Erling Smørgrav { FTS_DP, "dirl", "dirl" },
239*d30a84abSDag-Erling Smørgrav { FTS_F, "file", "file" },
240*d30a84abSDag-Erling Smørgrav { FTS_F, "filel", "filel" },
241*d30a84abSDag-Erling Smørgrav { FTS_NS, "noent", "noent" },
242*d30a84abSDag-Erling Smørgrav { 0 }
243*d30a84abSDag-Erling Smørgrav },
244*d30a84abSDag-Erling Smørgrav });
245*d30a84abSDag-Erling Smørgrav }
246*d30a84abSDag-Erling Smørgrav
247*d30a84abSDag-Erling Smørgrav ATF_TC(fts_options_physical);
ATF_TC_HEAD(fts_options_physical,tc)248*d30a84abSDag-Erling Smørgrav ATF_TC_HEAD(fts_options_physical, tc)
249*d30a84abSDag-Erling Smørgrav {
250*d30a84abSDag-Erling Smørgrav atf_tc_set_md_var(tc, "descr", "FTS_PHYSICAL");
251*d30a84abSDag-Erling Smørgrav }
ATF_TC_BODY(fts_options_physical,tc)252*d30a84abSDag-Erling Smørgrav ATF_TC_BODY(fts_options_physical, tc)
253*d30a84abSDag-Erling Smørgrav {
254*d30a84abSDag-Erling Smørgrav fts_options_prepare(tc);
255*d30a84abSDag-Erling Smørgrav fts_options_test(tc, &(struct fts_testcase){
256*d30a84abSDag-Erling Smørgrav all_paths,
257*d30a84abSDag-Erling Smørgrav FTS_PHYSICAL,
258*d30a84abSDag-Erling Smørgrav (struct fts_expect[]){
259*d30a84abSDag-Erling Smørgrav { FTS_SL, "dead", "dead" },
260*d30a84abSDag-Erling Smørgrav { FTS_D, "dir", "dir" },
261*d30a84abSDag-Erling Smørgrav { FTS_F, "file", "file" },
262*d30a84abSDag-Erling Smørgrav { FTS_SL, "up", "up" },
263*d30a84abSDag-Erling Smørgrav { FTS_DP, "dir", "dir" },
264*d30a84abSDag-Erling Smørgrav { FTS_SL, "dirl", "dirl" },
265*d30a84abSDag-Erling Smørgrav { FTS_F, "file", "file" },
266*d30a84abSDag-Erling Smørgrav { FTS_SL, "filel", "filel" },
267*d30a84abSDag-Erling Smørgrav { FTS_NS, "noent", "noent" },
268*d30a84abSDag-Erling Smørgrav { 0 }
269*d30a84abSDag-Erling Smørgrav },
270*d30a84abSDag-Erling Smørgrav });
271*d30a84abSDag-Erling Smørgrav }
272*d30a84abSDag-Erling Smørgrav
273*d30a84abSDag-Erling Smørgrav ATF_TC(fts_options_physical_nochdir);
ATF_TC_HEAD(fts_options_physical_nochdir,tc)274*d30a84abSDag-Erling Smørgrav ATF_TC_HEAD(fts_options_physical_nochdir, tc)
275*d30a84abSDag-Erling Smørgrav {
276*d30a84abSDag-Erling Smørgrav atf_tc_set_md_var(tc, "descr", "FTS_PHYSICAL | FTS_NOCHDIR");
277*d30a84abSDag-Erling Smørgrav }
ATF_TC_BODY(fts_options_physical_nochdir,tc)278*d30a84abSDag-Erling Smørgrav ATF_TC_BODY(fts_options_physical_nochdir, tc)
279*d30a84abSDag-Erling Smørgrav {
280*d30a84abSDag-Erling Smørgrav fts_options_prepare(tc);
281*d30a84abSDag-Erling Smørgrav fts_options_test(tc, &(struct fts_testcase){
282*d30a84abSDag-Erling Smørgrav all_paths,
283*d30a84abSDag-Erling Smørgrav FTS_PHYSICAL | FTS_NOCHDIR,
284*d30a84abSDag-Erling Smørgrav (struct fts_expect[]){
285*d30a84abSDag-Erling Smørgrav { FTS_SL, "dead", "dead" },
286*d30a84abSDag-Erling Smørgrav { FTS_D, "dir", "dir" },
287*d30a84abSDag-Erling Smørgrav { FTS_F, "file", "dir/file" },
288*d30a84abSDag-Erling Smørgrav { FTS_SL, "up", "dir/up" },
289*d30a84abSDag-Erling Smørgrav { FTS_DP, "dir", "dir" },
290*d30a84abSDag-Erling Smørgrav { FTS_SL, "dirl", "dirl" },
291*d30a84abSDag-Erling Smørgrav { FTS_F, "file", "file" },
292*d30a84abSDag-Erling Smørgrav { FTS_SL, "filel", "filel" },
293*d30a84abSDag-Erling Smørgrav { FTS_NS, "noent", "noent" },
294*d30a84abSDag-Erling Smørgrav { 0 }
295*d30a84abSDag-Erling Smørgrav },
296*d30a84abSDag-Erling Smørgrav });
297*d30a84abSDag-Erling Smørgrav }
298*d30a84abSDag-Erling Smørgrav
299*d30a84abSDag-Erling Smørgrav ATF_TC(fts_options_physical_comfollow);
ATF_TC_HEAD(fts_options_physical_comfollow,tc)300*d30a84abSDag-Erling Smørgrav ATF_TC_HEAD(fts_options_physical_comfollow, tc)
301*d30a84abSDag-Erling Smørgrav {
302*d30a84abSDag-Erling Smørgrav atf_tc_set_md_var(tc, "descr", "FTS_PHYSICAL | FTS_COMFOLLOW");
303*d30a84abSDag-Erling Smørgrav }
ATF_TC_BODY(fts_options_physical_comfollow,tc)304*d30a84abSDag-Erling Smørgrav ATF_TC_BODY(fts_options_physical_comfollow, tc)
305*d30a84abSDag-Erling Smørgrav {
306*d30a84abSDag-Erling Smørgrav fts_options_prepare(tc);
307*d30a84abSDag-Erling Smørgrav fts_options_test(tc, &(struct fts_testcase){
308*d30a84abSDag-Erling Smørgrav all_paths,
309*d30a84abSDag-Erling Smørgrav FTS_PHYSICAL | FTS_COMFOLLOW,
310*d30a84abSDag-Erling Smørgrav (struct fts_expect[]){
311*d30a84abSDag-Erling Smørgrav { FTS_DL, "dead", "dead" },
312*d30a84abSDag-Erling Smørgrav { FTS_D, "dir", "dir" },
313*d30a84abSDag-Erling Smørgrav { FTS_F, "file", "file" },
314*d30a84abSDag-Erling Smørgrav { FTS_SL, "up", "up" },
315*d30a84abSDag-Erling Smørgrav { FTS_DP, "dir", "dir" },
316*d30a84abSDag-Erling Smørgrav { FTS_D, "dirl", "dirl" },
317*d30a84abSDag-Erling Smørgrav { FTS_F, "file", "file" },
318*d30a84abSDag-Erling Smørgrav { FTS_SL, "up", "up" },
319*d30a84abSDag-Erling Smørgrav { FTS_DP, "dirl", "dirl" },
320*d30a84abSDag-Erling Smørgrav { FTS_F, "file", "file" },
321*d30a84abSDag-Erling Smørgrav { FTS_F, "filel", "filel" },
322*d30a84abSDag-Erling Smørgrav { FTS_NS, "noent", "noent" },
323*d30a84abSDag-Erling Smørgrav { 0 }
324*d30a84abSDag-Erling Smørgrav },
325*d30a84abSDag-Erling Smørgrav });
326*d30a84abSDag-Erling Smørgrav }
327*d30a84abSDag-Erling Smørgrav
328*d30a84abSDag-Erling Smørgrav ATF_TC(fts_options_physical_comfollowdir);
ATF_TC_HEAD(fts_options_physical_comfollowdir,tc)329*d30a84abSDag-Erling Smørgrav ATF_TC_HEAD(fts_options_physical_comfollowdir, tc)
330*d30a84abSDag-Erling Smørgrav {
331*d30a84abSDag-Erling Smørgrav atf_tc_set_md_var(tc, "descr", "FTS_PHYSICAL | FTS_COMFOLLOWDIR");
332*d30a84abSDag-Erling Smørgrav }
ATF_TC_BODY(fts_options_physical_comfollowdir,tc)333*d30a84abSDag-Erling Smørgrav ATF_TC_BODY(fts_options_physical_comfollowdir, tc)
334*d30a84abSDag-Erling Smørgrav {
335*d30a84abSDag-Erling Smørgrav fts_options_prepare(tc);
336*d30a84abSDag-Erling Smørgrav fts_options_test(tc, &(struct fts_testcase){
337*d30a84abSDag-Erling Smørgrav all_paths,
338*d30a84abSDag-Erling Smørgrav FTS_PHYSICAL | FTS_COMFOLLOWDIR,
339*d30a84abSDag-Erling Smørgrav (struct fts_expect[]){
340*d30a84abSDag-Erling Smørgrav { FTS_DL, "dead", "dead" },
341*d30a84abSDag-Erling Smørgrav { FTS_D, "dir", "dir" },
342*d30a84abSDag-Erling Smørgrav { FTS_F, "file", "file" },
343*d30a84abSDag-Erling Smørgrav { FTS_SL, "up", "up" },
344*d30a84abSDag-Erling Smørgrav { FTS_DP, "dir", "dir" },
345*d30a84abSDag-Erling Smørgrav { FTS_D, "dirl", "dirl" },
346*d30a84abSDag-Erling Smørgrav { FTS_F, "file", "file" },
347*d30a84abSDag-Erling Smørgrav { FTS_SL, "up", "up" },
348*d30a84abSDag-Erling Smørgrav { FTS_DP, "dirl", "dirl" },
349*d30a84abSDag-Erling Smørgrav { FTS_F, "file", "file" },
350*d30a84abSDag-Erling Smørgrav { FTS_SL, "filel", "filel" },
351*d30a84abSDag-Erling Smørgrav { FTS_NS, "noent", "noent" },
352*d30a84abSDag-Erling Smørgrav { 0 }
353*d30a84abSDag-Erling Smørgrav },
354*d30a84abSDag-Erling Smørgrav });
355*d30a84abSDag-Erling Smørgrav }
356*d30a84abSDag-Erling Smørgrav
357*d30a84abSDag-Erling Smørgrav ATF_TC(fts_options_physical_nostat);
ATF_TC_HEAD(fts_options_physical_nostat,tc)358*d30a84abSDag-Erling Smørgrav ATF_TC_HEAD(fts_options_physical_nostat, tc)
359*d30a84abSDag-Erling Smørgrav {
360*d30a84abSDag-Erling Smørgrav atf_tc_set_md_var(tc, "descr", "FTS_PHYSICAL | FTS_NOSTAT");
361*d30a84abSDag-Erling Smørgrav }
ATF_TC_BODY(fts_options_physical_nostat,tc)362*d30a84abSDag-Erling Smørgrav ATF_TC_BODY(fts_options_physical_nostat, tc)
363*d30a84abSDag-Erling Smørgrav {
364*d30a84abSDag-Erling Smørgrav fts_options_prepare(tc);
365*d30a84abSDag-Erling Smørgrav fts_options_test(tc, &(struct fts_testcase){
366*d30a84abSDag-Erling Smørgrav all_paths,
367*d30a84abSDag-Erling Smørgrav FTS_PHYSICAL | FTS_NOSTAT,
368*d30a84abSDag-Erling Smørgrav (struct fts_expect[]){
369*d30a84abSDag-Erling Smørgrav { FTS_SL, "dead", "dead" },
370*d30a84abSDag-Erling Smørgrav { FTS_D, "dir", "dir" },
371*d30a84abSDag-Erling Smørgrav { FTS_NSOK, "file", "file" },
372*d30a84abSDag-Erling Smørgrav { FTS_NSOK, "up", "up" },
373*d30a84abSDag-Erling Smørgrav { FTS_DP, "dir", "dir" },
374*d30a84abSDag-Erling Smørgrav { FTS_SL, "dirl", "dirl" },
375*d30a84abSDag-Erling Smørgrav { FTS_F, "file", "file" },
376*d30a84abSDag-Erling Smørgrav { FTS_SL, "filel", "filel" },
377*d30a84abSDag-Erling Smørgrav { FTS_NS, "noent", "noent" },
378*d30a84abSDag-Erling Smørgrav { 0 }
379*d30a84abSDag-Erling Smørgrav },
380*d30a84abSDag-Erling Smørgrav });
381*d30a84abSDag-Erling Smørgrav }
382*d30a84abSDag-Erling Smørgrav
383*d30a84abSDag-Erling Smørgrav ATF_TC(fts_options_physical_nostat_type);
ATF_TC_HEAD(fts_options_physical_nostat_type,tc)384*d30a84abSDag-Erling Smørgrav ATF_TC_HEAD(fts_options_physical_nostat_type, tc)
385*d30a84abSDag-Erling Smørgrav {
386*d30a84abSDag-Erling Smørgrav atf_tc_set_md_var(tc, "descr", "FTS_PHYSICAL | FTS_NOSTAT_TYPE");
387*d30a84abSDag-Erling Smørgrav }
ATF_TC_BODY(fts_options_physical_nostat_type,tc)388*d30a84abSDag-Erling Smørgrav ATF_TC_BODY(fts_options_physical_nostat_type, tc)
389*d30a84abSDag-Erling Smørgrav {
390*d30a84abSDag-Erling Smørgrav fts_options_prepare(tc);
391*d30a84abSDag-Erling Smørgrav fts_options_test(tc, &(struct fts_testcase){
392*d30a84abSDag-Erling Smørgrav all_paths,
393*d30a84abSDag-Erling Smørgrav FTS_PHYSICAL | FTS_NOSTAT_TYPE,
394*d30a84abSDag-Erling Smørgrav (struct fts_expect[]){
395*d30a84abSDag-Erling Smørgrav { FTS_SL, "dead", "dead" },
396*d30a84abSDag-Erling Smørgrav { FTS_D, "dir", "dir" },
397*d30a84abSDag-Erling Smørgrav { FTS_F, "file", "file" },
398*d30a84abSDag-Erling Smørgrav { FTS_SL, "up", "up" },
399*d30a84abSDag-Erling Smørgrav { FTS_DP, "dir", "dir" },
400*d30a84abSDag-Erling Smørgrav { FTS_SL, "dirl", "dirl" },
401*d30a84abSDag-Erling Smørgrav { FTS_F, "file", "file" },
402*d30a84abSDag-Erling Smørgrav { FTS_SL, "filel", "filel" },
403*d30a84abSDag-Erling Smørgrav { FTS_NS, "noent", "noent" },
404*d30a84abSDag-Erling Smørgrav { 0 }
405*d30a84abSDag-Erling Smørgrav },
406*d30a84abSDag-Erling Smørgrav });
407*d30a84abSDag-Erling Smørgrav }
408*d30a84abSDag-Erling Smørgrav
409*d30a84abSDag-Erling Smørgrav ATF_TC(fts_options_physical_seedot);
ATF_TC_HEAD(fts_options_physical_seedot,tc)410*d30a84abSDag-Erling Smørgrav ATF_TC_HEAD(fts_options_physical_seedot, tc)
411*d30a84abSDag-Erling Smørgrav {
412*d30a84abSDag-Erling Smørgrav atf_tc_set_md_var(tc, "descr", "FTS_PHYSICAL | FTS_SEEDOT");
413*d30a84abSDag-Erling Smørgrav }
ATF_TC_BODY(fts_options_physical_seedot,tc)414*d30a84abSDag-Erling Smørgrav ATF_TC_BODY(fts_options_physical_seedot, tc)
415*d30a84abSDag-Erling Smørgrav {
416*d30a84abSDag-Erling Smørgrav fts_options_prepare(tc);
417*d30a84abSDag-Erling Smørgrav fts_options_test(tc, &(struct fts_testcase){
418*d30a84abSDag-Erling Smørgrav all_paths,
419*d30a84abSDag-Erling Smørgrav FTS_PHYSICAL | FTS_SEEDOT,
420*d30a84abSDag-Erling Smørgrav (struct fts_expect[]){
421*d30a84abSDag-Erling Smørgrav { FTS_SL, "dead", "dead" },
422*d30a84abSDag-Erling Smørgrav { FTS_D, "dir", "dir" },
423*d30a84abSDag-Erling Smørgrav { FTS_DOT, ".", "." },
424*d30a84abSDag-Erling Smørgrav { FTS_DOT, "..", ".." },
425*d30a84abSDag-Erling Smørgrav { FTS_F, "file", "file" },
426*d30a84abSDag-Erling Smørgrav { FTS_SL, "up", "up" },
427*d30a84abSDag-Erling Smørgrav { FTS_DP, "dir", "dir" },
428*d30a84abSDag-Erling Smørgrav { FTS_SL, "dirl", "dirl" },
429*d30a84abSDag-Erling Smørgrav { FTS_F, "file", "file" },
430*d30a84abSDag-Erling Smørgrav { FTS_SL, "filel", "filel" },
431*d30a84abSDag-Erling Smørgrav { FTS_NS, "noent", "noent" },
432*d30a84abSDag-Erling Smørgrav { 0 }
433*d30a84abSDag-Erling Smørgrav },
434*d30a84abSDag-Erling Smørgrav });
435*d30a84abSDag-Erling Smørgrav }
436*d30a84abSDag-Erling Smørgrav
437*d30a84abSDag-Erling Smørgrav /*
438*d30a84abSDag-Erling Smørgrav * TODO: Add tests for FTS_XDEV and FTS_WHITEOUT
439*d30a84abSDag-Erling Smørgrav */
440*d30a84abSDag-Erling Smørgrav
ATF_TP_ADD_TCS(tp)441*d30a84abSDag-Erling Smørgrav ATF_TP_ADD_TCS(tp)
442*d30a84abSDag-Erling Smørgrav {
443*d30a84abSDag-Erling Smørgrav ATF_TP_ADD_TC(tp, fts_options_logical);
444*d30a84abSDag-Erling Smørgrav ATF_TP_ADD_TC(tp, fts_options_logical_nostat);
445*d30a84abSDag-Erling Smørgrav ATF_TP_ADD_TC(tp, fts_options_logical_seedot);
446*d30a84abSDag-Erling Smørgrav ATF_TP_ADD_TC(tp, fts_options_physical);
447*d30a84abSDag-Erling Smørgrav ATF_TP_ADD_TC(tp, fts_options_physical_nochdir);
448*d30a84abSDag-Erling Smørgrav ATF_TP_ADD_TC(tp, fts_options_physical_comfollow);
449*d30a84abSDag-Erling Smørgrav ATF_TP_ADD_TC(tp, fts_options_physical_comfollowdir);
450*d30a84abSDag-Erling Smørgrav ATF_TP_ADD_TC(tp, fts_options_physical_nostat);
451*d30a84abSDag-Erling Smørgrav ATF_TP_ADD_TC(tp, fts_options_physical_nostat_type);
452*d30a84abSDag-Erling Smørgrav ATF_TP_ADD_TC(tp, fts_options_physical_seedot);
453*d30a84abSDag-Erling Smørgrav return (atf_no_error());
454*d30a84abSDag-Erling Smørgrav }
455