]>
git.saurik.com Git - apple/libc.git/blob - tests/dir.c
6 #include <darwintest.h>
7 #include <darwintest_utils.h>
9 T_DECL(seekdir_basic
, "seekdir")
11 const char *path
= dt_tmpdir();
12 // make sure there are a couple of entries in the dir aside from . and ..
13 int fd
= open(path
, O_RDONLY
| O_DIRECTORY
);
14 openat(fd
, "a", O_CREAT
| O_WRONLY
, 0600);
15 openat(fd
, "b", O_CREAT
| O_WRONLY
, 0600);
16 openat(fd
, "c", O_CREAT
| O_WRONLY
, 0600);
18 DIR *dirp
= fdopendir(fd
);
19 struct dirent
*entry
= NULL
;
21 T_ASSERT_NOTNULL(dirp
, NULL
);
23 T_ASSERT_NOTNULL(entry
= readdir(dirp
), NULL
); // .
24 T_ASSERT_NOTNULL(entry
= readdir(dirp
), NULL
); // ..
26 // we can get any entry -- no ordering
27 T_ASSERT_NOTNULL(entry
= readdir(dirp
), NULL
);
28 // remember position for the second entry
29 long second_pos
= telldir(dirp
);
30 // read the second entry
31 T_ASSERT_NOTNULL(entry
= readdir(dirp
), NULL
);
32 char *second_name
= strdup(entry
->d_name
);
33 T_ASSERT_NOTNULL(second_name
, NULL
);
34 // read the third entry
35 T_ASSERT_NOTNULL(entry
= readdir(dirp
), NULL
);
37 // go back to the second entry and read it
38 seekdir(dirp
, second_pos
);
39 T_ASSERT_NOTNULL(entry
= readdir(dirp
), NULL
);
41 // make sure the name matches the old copy
42 T_ASSERT_EQ_STR(second_name
, entry
->d_name
, NULL
);
44 // return to 2nd once again, reinitializing second_pos and re-reading
45 seekdir(dirp
, second_pos
);
46 second_pos
= telldir(dirp
);
47 T_ASSERT_NOTNULL(entry
= readdir(dirp
), NULL
);
49 // make sure the name matches the old copy
50 T_ASSERT_EQ_STR(second_name
, entry
->d_name
, NULL
);
52 // verify that last pos
53 seekdir(dirp
, second_pos
);
54 T_ASSERT_NOTNULL(entry
= readdir(dirp
), NULL
);
55 T_ASSERT_EQ_STR(second_name
, entry
->d_name
, NULL
);
58 T_ASSERT_POSIX_ZERO(closedir(dirp
), NULL
);
61 T_DECL(readdir
, "readdir")
63 const char *path
= dt_tmpdir();
64 int fd
= open(path
, O_RDONLY
| O_DIRECTORY
);
65 openat(fd
, "foobarbaz", O_CREAT
| O_WRONLY
, 0600);
67 DIR *dirp
= fdopendir(fd
);
68 T_ASSERT_NOTNULL(dirp
, NULL
);
70 struct dirent
*entry
= NULL
;
71 while ((entry
= readdir(dirp
)) != NULL
) {
72 if (strcmp(entry
->d_name
, "foobarbaz")) {
77 T_ASSERT_NOTNULL(entry
, "found the entry");
79 T_ASSERT_POSIX_ZERO(closedir(dirp
), NULL
);
82 T_DECL(tell_seek_tell
, "tell-seek-tell returns the same location")
84 // http://pubs.opengroup.org/onlinepubs/009695399/functions/telldir.html
85 // If the most recent operation on the directory stream was a seekdir(),
86 // the directory position returned from the telldir() shall be the same as
87 // that supplied as a loc argument for seekdir().
89 const char *path
= dt_tmpdir();
90 // make sure there are a couple of entries in the dir aside from . and ..
92 int fd
= open(path
, O_RDONLY
| O_DIRECTORY
);
93 openat(fd
, "a", O_CREAT
| O_WRONLY
, 0600);
94 openat(fd
, "b", O_CREAT
| O_WRONLY
, 0600);
95 openat(fd
, "c", O_CREAT
| O_WRONLY
, 0600);
99 DIR *dirp
= opendir(path
);
100 T_ASSERT_NOTNULL(dirp
, NULL
);
101 struct dirent
*entry
= NULL
;
103 T_ASSERT_NOTNULL(entry
= readdir(dirp
), NULL
);
104 T_ASSERT_NOTNULL(entry
= readdir(dirp
), NULL
);
105 long pos1
= telldir(dirp
);
106 T_ASSERT_NOTNULL(entry
= readdir(dirp
), NULL
);
107 T_ASSERT_NOTNULL(entry
= readdir(dirp
), NULL
);
109 long pos2
= telldir(dirp
);
111 T_ASSERT_EQ(pos1
, pos2
, NULL
);
113 T_ASSERT_POSIX_ZERO(closedir(dirp
), NULL
);
116 T_DECL(rewinddir
, "rewinddir")
118 const char *path
= dt_tmpdir();
119 // make sure there are a couple of entries in the dir aside from . and ..
121 int fd
= open(path
, O_RDONLY
| O_DIRECTORY
);
122 openat(fd
, "a", O_CREAT
| O_WRONLY
, 0600);
123 openat(fd
, "b", O_CREAT
| O_WRONLY
, 0600);
124 openat(fd
, "c", O_CREAT
| O_WRONLY
, 0600);
128 DIR *dirp
= opendir(path
);
129 T_ASSERT_NOTNULL(dirp
, NULL
);
130 struct dirent
*entry
= NULL
;
132 T_ASSERT_NOTNULL(entry
= readdir(dirp
), NULL
);
133 T_ASSERT_NOTNULL(entry
= readdir(dirp
), NULL
);
134 T_ASSERT_NOTNULL(entry
= readdir(dirp
), NULL
);
135 char *third_name
= strdup(entry
->d_name
);
139 T_ASSERT_NOTNULL(entry
= readdir(dirp
), NULL
);
140 T_ASSERT_NOTNULL(entry
= readdir(dirp
), NULL
);
141 T_ASSERT_NOTNULL(entry
= readdir(dirp
), NULL
);
143 T_ASSERT_EQ_STR(third_name
, entry
->d_name
, NULL
);
146 T_ASSERT_POSIX_ZERO(closedir(dirp
), NULL
);
150 T_DECL(rewinddir_dup
, "rewinddir dup")
152 // An older implementation of rewinddir failed to seek the fd which was
153 // passed to fdopendir()
155 const char *path
= dt_tmpdir();
156 // make sure there are a couple of entries in the dir aside from . and ..
157 int fd
= open(path
, O_RDONLY
| O_DIRECTORY
);
158 openat(fd
, "a", O_CREAT
| O_WRONLY
, 0600);
159 openat(fd
, "b", O_CREAT
| O_WRONLY
, 0600);
160 openat(fd
, "c", O_CREAT
| O_WRONLY
, 0600);
162 // prep an fd with a non-zero seek
163 DIR *dirp
= fdopendir(fd
);
164 T_ASSERT_NOTNULL(dirp
, NULL
);
165 struct dirent
*entry
= NULL
;
167 T_ASSERT_NOTNULL(entry
= readdir(dirp
), NULL
);
168 T_ASSERT_NOTNULL(entry
= readdir(dirp
), NULL
);
169 T_ASSERT_NOTNULL(entry
= readdir(dirp
), NULL
);
171 // remember the entry name and dup the fd
172 char *third_name
= strdup(entry
->d_name
);
175 T_ASSERT_POSIX_ZERO(closedir(dirp
), NULL
);
177 dirp
= fdopendir(fd2
);
181 T_ASSERT_NOTNULL(dirp
, NULL
);
182 T_ASSERT_NOTNULL(entry
= readdir(dirp
), NULL
);
183 T_ASSERT_NOTNULL(entry
= readdir(dirp
), NULL
);
184 T_ASSERT_NOTNULL(entry
= readdir(dirp
), NULL
);
186 T_ASSERT_EQ_STR(third_name
, entry
->d_name
, NULL
);
189 T_ASSERT_POSIX_ZERO(closedir(dirp
), NULL
);
193 _select_abc(const struct dirent
*entry
)
195 return strcmp(entry
->d_name
, "a") == 0 ||
196 strcmp(entry
->d_name
, "b") == 0 ||
197 strcmp(entry
->d_name
, "c") == 0;
200 T_DECL(scandir
, "scandir")
202 const char *path
= dt_tmpdir();
204 int fd
= open(path
, O_RDONLY
| O_DIRECTORY
);
205 openat(fd
, "a", O_CREAT
| O_WRONLY
, 0600);
206 openat(fd
, "b", O_CREAT
| O_WRONLY
, 0600);
207 openat(fd
, "c", O_CREAT
| O_WRONLY
, 0600);
211 struct dirent
**entries
= NULL
;
212 int found
= scandir(path
, &entries
, _select_abc
, alphasort
);
214 T_ASSERT_EQ(found
, 3, NULL
);
216 T_ASSERT_EQ_STR(entries
[0]->d_name
, "a", NULL
);
217 T_ASSERT_EQ_STR(entries
[1]->d_name
, "b", NULL
);
218 T_ASSERT_EQ_STR(entries
[2]->d_name
, "c", NULL
);
226 T_DECL(scandir_b
, "scandir_b")
228 const char *path
= dt_tmpdir();
230 int fd
= open(path
, O_RDONLY
| O_DIRECTORY
);
231 openat(fd
, "a", O_CREAT
| O_WRONLY
, 0600);
232 openat(fd
, "b", O_CREAT
| O_WRONLY
, 0600);
233 openat(fd
, "c", O_CREAT
| O_WRONLY
, 0600);
237 const struct dirent
**entries
= NULL
;
238 int found
= scandir_b(path
, &entries
,
239 ^(const struct dirent
*entry
) {
240 return strcmp(entry
->d_name
, "a") == 0 ||
241 strcmp(entry
->d_name
, "b") == 0 ||
242 strcmp(entry
->d_name
, "c") == 0;
244 ^(const struct dirent
**d1
, const struct dirent
**d2
) {
245 return strcoll((*d1
)->d_name
, (*d2
)->d_name
);
248 T_ASSERT_EQ(found
, 3, NULL
);
250 T_ASSERT_EQ_STR(entries
[0]->d_name
, "a", NULL
);
251 T_ASSERT_EQ_STR(entries
[1]->d_name
, "b", NULL
);
252 T_ASSERT_EQ_STR(entries
[2]->d_name
, "c", NULL
);