]>
git.saurik.com Git - apple/libc.git/blob - tests/fts_simple.c
12 #include <darwintest.h>
13 #include <darwintest_utils.h>
16 _create_random_file(int root_fd
, char *path
)
18 int fd
= openat(root_fd
, path
, O_WRONLY
| O_CREAT
);
19 T_ASSERT_POSIX_SUCCESS(fd
, NULL
);
20 T_ASSERT_POSIX_SUCCESS(dprintf(fd
, "Random File at: %s", path
), NULL
);
21 T_ASSERT_POSIX_SUCCESS(close(fd
), NULL
);
25 _create_symlink(char *root
, char *destination
, char *source
)
27 char *absolute_destination
= NULL
;
28 T_ASSERT_POSIX_SUCCESS(asprintf(&absolute_destination
, "%s/%s", root
, destination
), NULL
);
29 char *absolute_source
= NULL
;
30 T_ASSERT_POSIX_SUCCESS(asprintf(&absolute_source
, "%s/%s", root
, source
), NULL
);
31 T_ASSERT_POSIX_SUCCESS(symlink(absolute_destination
, absolute_source
), NULL
);
32 free(absolute_destination
);
33 free(absolute_source
);
37 _remove_prefix(char *prefix
, char *input
) {
38 char *start
= strstr(input
, prefix
);
40 T_ASSERT_NOTNULL(start
, "prefix: %s input: %s", prefix
, input
);
41 char *end
= start
+ strlen(prefix
) + 1;
45 T_DECL(fts_simple
, "Simple fts_read test")
47 T_LOG("prog: %s", getprogname());
48 char *tmp_path
= NULL
;
49 T_ASSERT_POSIX_SUCCESS(asprintf(&tmp_path
, "%s/%s-XXXXXX", dt_tmpdir(), T_NAME
), NULL
);
50 T_ASSERT_NOTNULL(mktemp(tmp_path
), NULL
);
51 T_ASSERT_POSIX_SUCCESS(mkdir(tmp_path
, 0777), NULL
);
52 int tmp_fd
= open(tmp_path
, O_RDONLY
| O_DIRECTORY
);
53 T_LOG("tmp: %s", tmp_path
);
54 T_ASSERT_POSIX_SUCCESS(tmp_fd
, NULL
);
56 T_ASSERT_POSIX_SUCCESS(mkdirat(tmp_fd
, "A", 0777), NULL
);
57 T_ASSERT_POSIX_SUCCESS(mkdirat(tmp_fd
, "A/B", 0777), NULL
);
58 T_ASSERT_POSIX_SUCCESS(mkdirat(tmp_fd
, "A/C", 0777), NULL
);
59 T_ASSERT_POSIX_SUCCESS(mkdirat(tmp_fd
, "A/B/D", 0777), NULL
);
60 T_ASSERT_POSIX_SUCCESS(mkdirat(tmp_fd
, "A/C/empty", 0777), NULL
);
61 _create_random_file(tmp_fd
, "root");
62 _create_random_file(tmp_fd
, "A/fileA1");
63 _create_random_file(tmp_fd
, "A/fileA2");
64 _create_random_file(tmp_fd
, "A/B/fileB1");
65 _create_random_file(tmp_fd
, "A/C/fileC1");
66 _create_random_file(tmp_fd
, "A/B/D/fileD1");
67 T_ASSERT_POSIX_SUCCESS(mkdirat(tmp_fd
, "LINK", 0777), NULL
);
68 T_ASSERT_POSIX_SUCCESS(mkdirat(tmp_fd
, "LINK/Z", 0777), NULL
);
69 _create_random_file(tmp_fd
, "LINK/fileL1");
70 _create_random_file(tmp_fd
, "LINK/Z/fileZ1");
71 _create_symlink(tmp_path
, "LINK", "A/link");
73 char original_cwd
[MAXPATHLEN
];
74 T_ASSERT_NOTNULL(getcwd(original_cwd
, sizeof(original_cwd
)), NULL
);
104 .path
= "A/B/D/fileD1",
114 .path
= "A/B/fileB1",
139 .path
= "A/C/fileC1",
159 .path
= "A/link/fileL1",
169 .path
= "A/link/Z/fileZ1",
194 const char *LABELS
[] = {
196 [FTS_D
] = "FTS_D", /* preorder directory */
197 [FTS_DC
] = "FTS_DC", /* directory that causes cycles */
198 [FTS_DEFAULT
] = "FTS_DEFAULT", /* none of the above */
199 [FTS_DNR
] = "FTS_DNR", /* unreadable directory */
200 [FTS_DOT
] = "FTS_DOT", /* dot or dot-dot */
201 [FTS_DP
] = "FTS_DP", /* postorder directory */
202 [FTS_ERR
] = "FTS_ERR", /* error; errno is set */
203 [FTS_F
] = "FTS_F", /* regular file */
204 [FTS_INIT
] = "FTS_INIT", /* initialized only */
205 [FTS_NS
] = "FTS_NS", /* stat(2) failed */
206 [FTS_NSOK
] = "FTS_NSOK", /* no stat(2) requested */
207 [FTS_SL
] = "FTS_SL", /* symbolic link */
208 [FTS_SLNONE
] = "FTS_SLNONE", /* symbolic link without target */
211 char *root_path
= NULL
;
212 T_ASSERT_POSIX_SUCCESS(asprintf(&root_path
, "%s/A", tmp_path
), NULL
);
213 const char *paths
[] = {
217 FTS
*tree
= fts_open(paths
, FTS_PHYSICAL
, NULL
);
218 T_ASSERT_NOTNULL(tree
, NULL
);
221 while ((node
= fts_read(tree
))) {
222 char cwd
[MAXPATHLEN
];
224 T_ASSERT_NOTNULL(getcwd(cwd
, sizeof(cwd
)), NULL
);
226 switch (node
->fts_info
) {
228 T_FAIL("FTS_ERR(%d)", node
->fts_errno
);
231 fts_set(tree
, node
, FTS_FOLLOW
);
235 for (size_t index
= 0; index
< countof(expected
) && !found
; index
++) {
236 if (expected
[index
].found
) {
239 if (expected
[index
].info
!= node
->fts_info
) {
244 char *expected_path
= expected
[index
].path
;
245 char *actual_path
= node
->fts_path
;
246 if (expected_path
[0] != '/') {
247 actual_path
= _remove_prefix(tmp_path
, actual_path
);
250 if (strcmp(actual_path
, expected_path
) == 0) {
251 char *expected_cwd
= expected
[index
].cwd
;
252 char *actual_cwd
= cwd
;
253 if (expected_cwd
[0] != '/') {
255 actual_cwd
= _remove_prefix(tmp_path
, actual_cwd
);
258 T_EXPECT_EQ_STR(actual_cwd
, expected_cwd
, NULL
);
260 expected
[index
].found
= true;
264 T_EXPECT_TRUE(found
, "path: %s info: %d [%s] cwd: %s", node
->fts_path
, node
->fts_info
, LABELS
[node
->fts_info
], cwd
);
269 T_EXPECT_EQ(found_count
, countof(expected
), NULL
);
270 for (size_t index
= 0; index
< countof(expected
); index
++) {
272 T_EXPECT_TRUE(expected
[index
].found
, "missing: path: %s info %d [%s]", expected
[index
].path
, expected
[index
].info
, LABELS
[expected
[index
].info
]);