1 /*- 2 * Copyright (c) 2025 Klara, Inc. 3 * 4 * SPDX-License-Identifier: BSD-2-Clause 5 */ 6 7 #include <sys/stat.h> 8 9 #include <fcntl.h> 10 #include <fts.h> 11 12 #include <atf-c.h> 13 14 /* 15 * Create two directories with three files each in lexicographical order, 16 * then call FTS with a sort block that sorts in reverse lexicographical 17 * order. This has the least chance of getting a false positive due to 18 * differing file system semantics. UFS will return the files in the 19 * order they were created while ZFS will sort them lexicographically; in 20 * both cases, the order we expect is the reverse. 21 */ 22 ATF_TC_WITHOUT_HEAD(fts_blocks_test); 23 ATF_TC_BODY(fts_blocks_test, tc) 24 { 25 char *args[] = { 26 "bar", "foo", NULL 27 }; 28 char *paths[] = { 29 "foo", "z", "y", "x", "foo", 30 "bar", "c", "b", "a", "bar", 31 NULL 32 }; 33 char **expect = paths; 34 FTS *fts; 35 FTSENT *ftse; 36 37 ATF_REQUIRE_EQ(0, mkdir("bar", 0755)); 38 ATF_REQUIRE_EQ(0, close(creat("bar/a", 0644))); 39 ATF_REQUIRE_EQ(0, close(creat("bar/b", 0644))); 40 ATF_REQUIRE_EQ(0, close(creat("bar/c", 0644))); 41 ATF_REQUIRE_EQ(0, mkdir("foo", 0755)); 42 ATF_REQUIRE_EQ(0, close(creat("foo/x", 0644))); 43 ATF_REQUIRE_EQ(0, close(creat("foo/y", 0644))); 44 ATF_REQUIRE_EQ(0, close(creat("foo/z", 0644))); 45 fts = fts_open_b(args, 0, 46 ^(const FTSENT * const *a, const FTSENT * const *b) { 47 return (strcmp((*b)->fts_name, (*a)->fts_name)); 48 }); 49 ATF_REQUIRE_MSG(fts != NULL, "fts_open_b(): %m"); 50 while ((ftse = fts_read(fts)) != NULL && *expect != NULL) { 51 ATF_CHECK_STREQ(*expect, ftse->fts_name); 52 expect++; 53 } 54 ATF_CHECK_EQ(NULL, ftse); 55 ATF_CHECK_EQ(NULL, *expect); 56 ATF_REQUIRE_EQ_MSG(0, fts_close(fts), "fts_close(): %m"); 57 } 58 59 ATF_TP_ADD_TCS(tp) 60 { 61 ATF_TP_ADD_TC(tp, fts_blocks_test); 62 return (atf_no_error()); 63 } 64