]>
git.saurik.com Git - apple/libc.git/blob - tests/fts_find.c
4dcb26f989ce6750d4f365e407f134ddc63a8669
12 // Can ASan fts by uncommenting below
13 //#include "../gen/fts.c"
16 #define fts_find_main main
18 #include <darwintest.h>
21 int fts_find_main(int argc
, char *argv
[]);
25 stat_str(struct stat
*st
)
27 static char charbuf
[256];
28 snprintf(charbuf
, sizeof(charbuf
), "dev: %d, mode: %x, nlink: %d, ino: %lld, "
29 "owner: %d/%d, rdev: %d, mtime: %ld, ctime: %ld, btime: %ld, "
30 "size: %lld, blocks: %lld, blksize: %d, flags: %d, gen: %d",
31 st
->st_dev
, st
->st_mode
, st
->st_nlink
, st
->st_ino
, st
->st_uid
,
32 st
->st_gid
, st
->st_rdev
, st
->st_mtimespec
.tv_sec
,
33 st
->st_ctimespec
.tv_sec
, st
->st_birthtimespec
.tv_sec
, st
->st_size
,
34 st
->st_blocks
, st
->st_blksize
, st
->st_flags
, st
->st_gen
);
40 fts_find_main(int argc
, char *argv
[])
45 bool print_children
= false;
46 int fts_options
= FTS_COMFOLLOW
| FTS_XDEV
;
51 while ((ch
= getopt(argc
, argv
, "lpcdsS")) != -1){
54 fts_options
|= FTS_LOGICAL
;
57 fts_options
|= FTS_PHYSICAL
;
60 print_children
= true;
63 fts_options
|= FTS_NOCHDIR
;
66 fts_options
|= FTS_NOSTAT
;
69 fts_options
|= FTS_NOSTAT_TYPE
;
72 fprintf(stderr
, "Usage: %s (-l|-p) [-c] [-d] [-s|-S] <path> ...\n", argv
[0]);
77 if ((fts_options
& (FTS_LOGICAL
|FTS_PHYSICAL
)) == 0){
78 fprintf(stderr
, "Usage: %s (-l|-p) [-c] [-s|-S] <path> ...\n", argv
[0]);
85 char **args
= alloca((size_t)(argc
+ 1)*sizeof(char*));
86 for (int i
= 0; i
< argc
; i
++){
90 fts
= fts_open_b(args
, fts_options
, ^(const FTSENT
**a
, const FTSENT
**b
){
91 return strcmp((*a
)->fts_name
, (*b
)->fts_name
);
93 if (!fts
) err(EX_DATAERR
, "fts_open_b");
95 while ((ftse
= fts_read(fts
)) != NULL
) {
97 if (!print_children
|| (ftse
->fts_info
& FTS_D
)){
98 printf("%s (%s): 0x%x\n", ftse
->fts_path
, ftse
->fts_name
, ftse
->fts_info
);
99 if (!(fts_options
& (FTS_NOSTAT
|FTS_NOSTAT_TYPE
))) printf("\t\t%s\n", stat_str(ftse
->fts_statp
));
103 FTSENT
*child
= fts_children(fts
, 0);
106 if (child
->fts_info
& FTS_F
){
107 printf("\t%s (%s): 0x%x\n", child
->fts_path
, child
->fts_name
, child
->fts_info
);
108 if (!(fts_options
& (FTS_NOSTAT
|FTS_NOSTAT_TYPE
))) printf("\t\t%s\n", stat_str(child
->fts_statp
));
111 child
= child
->fts_link
;
116 (void)fts_close(fts
);
121 T_DECL(fts_find
, "A find(1) example in fts"){
123 char *fts_argv
[] = {"fts_find", "-lc", "/System", NULL
};
124 if (fts_find_main(fts_argc
, fts_argv
) == 0){
125 T_PASS("fts_find() completed successfully");
127 T_FAIL("fts_find() exited with error");
131 T_DECL(fts_find_empty_path
, "Test result for empty path"){
132 char *paths
[] = {"/System", "", NULL
};
134 FTS
*fts
= fts_open_b(paths
, 0, ^(const FTSENT
**a
, const FTSENT
**b
){
135 return strcmp((*a
)->fts_name
, (*b
)->fts_name
);
138 T_FAIL("fts_open() failed");
142 // The first entry name should be the empty string, because of the sort
143 // order. The second entry should be "System".
144 FTSENT
*entry
= fts_read(fts
);
145 T_ASSERT_NOTNULL(entry
, "First fts_read() returned NULL");
146 T_ASSERT_EQ_STR(entry
->fts_name
, "", "First entry name is empty");
147 T_ASSERT_EQ((int)entry
->fts_info
, FTS_NS
, "First fts_info is FTS_NS");
148 T_ASSERT_EQ(entry
->fts_errno
, ENOENT
, "First fts_errno is ENOENT");
150 entry
= fts_read(fts
);
151 T_ASSERT_NOTNULL(entry
, "Second fts_read() returned NULL");
152 T_ASSERT_EQ_STR(entry
->fts_name
, "System", "Second entry name is System");
153 T_ASSERT_EQ((int)entry
->fts_info
, FTS_D
, "Second fts_info is FTS_D");
154 T_ASSERT_EQ(entry
->fts_errno
, 0, "Second fts_errno is 0");