1 /* Test24: opendir, readdir, rewinddir, closedir Author: Jan-Mark Wams */
16 _PROTOTYPE(void main
, (int argc
, char *argv
[]));
17 _PROTOTYPE(void chk_dir
, (DIR * dirpntr
));
18 _PROTOTYPE(void test24a
, (void));
19 _PROTOTYPE(void test24b
, (void));
20 _PROTOTYPE(void test24c
, (void));
21 _PROTOTYPE(void makelongnames
, (void));
22 _PROTOTYPE(void e
, (int number
));
23 _PROTOTYPE(void quit
, (void));
25 #define OVERFLOW_DIR_NR (OPEN_MAX + 1)
29 #define DIRENT0 ((struct dirent *) NULL)
30 #define System(cmd) if (system(cmd) != 0) printf("``%s'' failed\n", cmd)
31 #define Chdir(dir) if (chdir(dir) != 0) printf("Can't goto %s\n", dir)
37 char MaxName
[NAME_MAX
+ 1]; /* Name of maximum length */
38 char MaxPath
[PATH_MAX
]; /* Same for path */
39 char ToLongName
[NAME_MAX
+ 2]; /* Name of maximum +1 length */
40 char ToLongPath
[PATH_MAX
+ 1]; /* Same for path, both too long */
49 if (argc
== 2) m
= atoi(argv
[1]);
52 System("rm -rf DIR_24; mkdir DIR_24");
55 superuser
= (geteuid() == 0);
57 for (i
= 0; i
< ITERATIONS
; i
++) {
58 if (m
& 0001) test24a();
59 if (m
& 0002) test24b();
60 if (m
& 0004) test24c();
66 { /* Test normal operations. */
69 int j
, ret
, fd
, flags
;
76 System("rm -rf ../DIR_24/*");
78 if ((fd
= dup(0)) != 3) e(1); /* dup stdin */
79 close(fd
); /* free the fd again */
80 dirp
= opendir("/"); /* open "/" */
81 if (dirp
== ((DIR *) NULL
)) e(2); /* has to succseed */
82 if ((fd
= dup(0)) <= 2) e(3); /* dup stdin */
83 if (fd
> 3) { /* if opendir() uses fd 3 */
84 flags
= fcntl(3, F_GETFD
); /* get fd fags of 3 */
85 if (!(flags
& FD_CLOEXEC
)) e(4); /* it should be closed on */
86 } /* exec..() calls */
87 close(fd
); /* free the fd again */
88 ret
= closedir(dirp
); /* close, we don't need it */
89 if (ret
== -1) e(5); /* closedir () unsucces full */
90 if (ret
!= 0) e(6); /* should be 0 or -1 */
91 if ((fd
= dup(0)) != 3) e(7); /* see if next fd is same */
92 close(fd
); /* free the fd again */
94 System("rm -rf foo; mkdir foo");
96 System("touch f1 f2 f3 f4 f5"); /* make f1 .. f5 */
97 System("rm f[24]"); /* creat `holes' in entrys */
100 if ((dirp
= opendir("foo")) == ((DIR *) NULL
)) e(8); /* open foo */
101 chk_dir(dirp
); /* test if foo's ok */
102 for (j
= 0; j
< 10; j
++) {
103 errno
= j
* 47 % 7; /* there should */
104 if (readdir(dirp
) != DIRENT0
) e(9); /* be nomore dir */
105 if (errno
!= j
* 47 % 7) e(10); /* entrys */
107 rewinddir(dirp
); /* rewind foo */
108 chk_dir(dirp
); /* test foosok */
109 for (j
= 0; j
< 10; j
++) {
110 errno
= j
* 23 % 7; /* there should */
111 if (readdir(dirp
) != DIRENT0
) e(11); /* be nomore dir */
112 if (errno
!= j
* 23 % 7) e(12); /* entrys */
114 if ((fd4
= creat("foo/f4", 0666)) <= 2) e(13); /* Open a file. */
115 System("rm foo/f4"); /* Kill entry. */
116 rewinddir(dirp
); /* Rewind foo. */
117 if ((fd3
= open("foo/f3", O_WRONLY
)) <= 2) e(14); /* Open more files. */
118 if ((fd5
= open("foo/f5", O_WRONLY
)) <= 2) e(15);
119 if (write(fd3
, "Hello", 6) != 6) e(16);
120 if (write(fd4
, "Hello", 6) != 6) e(17); /* write some data */
121 if (close(fd5
) != 0) e(18);
123 for (j
= 0; j
< 10; j
++) {
124 errno
= j
* 101 % 7; /* there should */
125 if (readdir(dirp
) != DIRENT0
) e(19); /* be nomore dir */
126 if (errno
!= j
* 101 % 7) e(20); /* entrys */
128 if (close(fd4
) != 0) e(21); /* shouldn't matter */
129 if (close(fd3
) != 0) e(22); /* when we do this */
130 if (closedir(dirp
) != 0) e(23); /* close foo again */
133 if ((dirp
= opendir(".//")) == ((DIR *) NULL
)) e(24); /* open foo again */
135 chk_dir(dirp
); /* foosok? */
136 for (j
= 0; j
< 10; j
++) {
137 errno
= (j
* 101) % 7; /* there should */
138 if (readdir(dirp
) != DIRENT0
) e(25); /* be nomore dir */
139 if (errno
!= (j
* 101) % 7) e(26); /* entrys */
142 if (closedir(dirp
) != 0) e(27); /* It should be closable */
144 stat("foo", &st1
); /* get stat */
146 while (time1
>= time((time_t *)0))
148 if ((dirp
= opendir("foo")) == ((DIR *) NULL
)) e(28); /* open, */
149 if (readdir(dirp
) == DIRENT0
) e(29); /* read and */
150 stat("foo", &st2
); /* get new stat */
151 if (st1
.st_atime
> st2
.st_atime
) e(30); /* st_atime check */
154 case -1: printf("Can't fork\n"); break;
156 rewinddir(dirp
); /* rewind childs dirp */
157 if (readdir(dirp
) == DIRENT0
) e(31); /* read should be ok */
158 if (closedir(dirp
) != 0) e(32); /* close child'd foo */
159 exit(0); /* 0 stops here */
161 if (wait(&stat_loc
) == -1) e(33); /* PARENT wait()'s */
164 if (closedir(dirp
) != 0) e(34); /* close parent's foo */
169 /* See what happens with too many dir's open. Check if file size seems ok,
173 int i
, j
; /* i = highest open dir count */
174 DIR *dirp
[OVERFLOW_DIR_NR
], *dp
;
175 struct dirent
*dep
, *dep1
, *dep2
;
176 char name
[NAME_MAX
+ 2]; /* buffer for file name, and count */
177 int dot
= 0, dotdot
= 0;
181 System("rm -rf ../DIR_24/*");
183 for (i
= 0; i
< OVERFLOW_DIR_NR
; i
++) {
184 dirp
[i
] = opendir("/");
185 if (dirp
[i
] == ((DIR *) NULL
)) {
186 if (errno
!= EMFILE
) e(1);
190 if (i
<= 4) e(2); /* sounds resanable */
191 if (i
>= OVERFLOW_DIR_NR
) e(3); /* might be to small */
192 for (j
= 0; j
< i
; j
++) {
193 if (closedir(dirp
[(j
+ 5) % i
]) != 0) e(4); /* neat! */
196 /* Now check if number of bytes in d_name can go up till NAME_MAX */
197 System("rm -rf foo; mkdir foo");
200 for (i
= 0; i
<= NAME_MAX
; i
++) {
201 if (strcat(name
, "X") != name
) e(5);
202 close(creat(name
, 0666)); /* fails once on */
203 } /* XX..XX, 1 too long */
205 /* Now change i-th X to Y in name buffer record file of length i. */
206 if ((dp
= opendir("foo")) == ((DIR *) NULL
)) e(6);
207 while ((dep
= readdir(dp
)) != DIRENT0
) {
208 if (strcmp("..", dep
->d_name
) == 0)
210 else if (strcmp(".", dep
->d_name
) == 0)
213 name
[strlen(dep
->d_name
)] += 1; /* 'X' + 1 == 'Y' */
215 if (closedir(dp
) != 0) e(7);
216 for (i
= 1; i
<= NAME_MAX
; i
++) { /* Check if every length */
217 if (name
[i
] != 'Y') e(8); /* has been seen once. */
220 /* Check upper and lower bound. */
221 if (name
[0] != 'X') e(9);
222 if (name
[NAME_MAX
+ 1] != '\0') e(10);
224 /* Now check if two simultaniouse open dirs do the same */
225 if ((dirp
[1] = opendir("foo")) == ((DIR *) NULL
)) e(11);
226 if ((dirp
[2] = opendir("foo")) == ((DIR *) NULL
)) e(12);
227 if ((dep1
= readdir(dirp
[1])) == DIRENT0
) e(13);
228 if ((dep2
= readdir(dirp
[2])) == DIRENT0
) e(14);
229 if (dep1
->d_name
== dep2
->d_name
) e(15); /* 1 & 2 Should be */
230 strcpy(name
, dep2
->d_name
); /* differand buffers */
231 if (strcmp(dep1
->d_name
, name
) != 0) e(16); /* But hold the same */
232 if ((dep1
= readdir(dirp
[1])) == DIRENT0
) e(17);
233 if ((dep1
= readdir(dirp
[1])) == DIRENT0
) e(18); /* lose some entries */
234 if ((dep1
= readdir(dirp
[1])) == DIRENT0
) e(19); /* Using dirp 1 has */
235 if (dep1
->d_name
== dep2
->d_name
) e(20); /* no effect on 2 */
236 if (strcmp(dep2
->d_name
, name
) != 0) e(21);
237 rewinddir(dirp
[1]); /* Rewinding dirp 1 */
238 if ((dep2
= readdir(dirp
[2])) == DIRENT0
) e(22); /* can't effect 2 */
239 if (strcmp(dep2
->d_name
, name
) == 0) e(23); /* Must be next */
240 if (closedir(dirp
[1]) != 0) e(24); /* Closing dirp 1 */
241 if ((dep2
= readdir(dirp
[2])) == DIRENT0
) e(25); /* can't effect 2 */
242 if (strcmp(dep2
->d_name
, name
) == 0) e(26); /* Must be next */
243 if (closedir(dirp
[2]) != 0) e(27);
248 /* Test whether wrong things go wrong right. */
254 System("rm -rf ../DIR_24/*");
256 if (opendir("foo/bar/nono") != ((DIR *) NULL
)) e(1); /* nonexistent */
257 if (errno
!= ENOENT
) e(2);
258 System("mkdir foo; chmod 677 foo"); /* foo inaccesable */
259 if (opendir("foo/bar/nono") != ((DIR *) NULL
)) e(3);
261 if (errno
!= ENOENT
) e(4); /* su has access */
262 System("chmod 377 foo");
263 if ((dirp
= opendir("foo")) == ((DIR *) NULL
)) e(5);
264 if (closedir(dirp
) != 0) e(6);
267 if (errno
!= EACCES
) e(7); /* we don't ;-) */
268 System("chmod 377 foo");
269 if (opendir("foo") != ((DIR *) NULL
)) e(8);
271 System("chmod 777 foo");
273 if (mkdir(MaxName
, 0777) != 0) e(9); /* make longdir */
274 if ((dirp
= opendir(MaxName
)) == ((DIR *) NULL
)) e(10); /* open it */
275 if (closedir(dirp
) != 0) e(11); /* close it */
276 if (rmdir(MaxName
) != 0) e(12); /* then remove it */
277 if ((dirp
= opendir(MaxPath
)) == ((DIR *) NULL
)) e(13); /* open '.' */
278 if (closedir(dirp
) != 0) e(14); /* close it */
279 #if 0 /* XXX - anything could happen with the bad pointer */
280 if (closedir(dirp
) != -1) e(15); /* close it again */
281 if (closedir(dirp
) != -1) e(16); /* and again */
283 if (opendir(ToLongName
) != ((DIR *) NULL
)) e(17); /* is too long */
284 #ifdef _POSIX_NO_TRUNC
285 # if _POSIX_NO_TRUNC - 0 != -1
286 if (errno
!= ENAMETOOLONG
) e(18);
288 if (errno
!= ENOENT
) e(19);
291 # include "error, this case requires dynamic checks and is not handled"
293 if (opendir(ToLongPath
) != ((DIR *) NULL
)) e(20); /* path is too long */
294 if (errno
!= ENAMETOOLONG
) e(21);
295 System("touch foo/abc"); /* make a file */
296 if (opendir("foo/abc") != ((DIR *) NULL
)) e(22); /* not a dir */
297 if (errno
!= ENOTDIR
) e(23);
300 void chk_dir(dirp
) /* dir should contain */
301 DIR *dirp
; /* (`f1', `f3', `f5', `.', `..') */
302 { /* no more, no less */
303 int f1
= 0, f2
= 0, f3
= 0, f4
= 0, f5
= 0, /* counters for all */
304 other
= 0, dot
= 0, dotdot
= 0; /* possible entrys */
308 int oldsubtest
= subtest
;
312 for (i
= 0; i
< 5; i
++) { /* 3 files and `.' and `..' == 5 entrys */
314 if (dep
== DIRENT0
) { /* not einough */
315 if (dep
== DIRENT0
) e(1);
319 if (strcmp(fname
, ".") == 0)
321 else if (strcmp(fname
, "..") == 0)
323 else if (strcmp(fname
, "f1") == 0)
325 else if (strcmp(fname
, "f2") == 0)
327 else if (strcmp(fname
, "f3") == 0)
329 else if (strcmp(fname
, "f4") == 0)
331 else if (strcmp(fname
, "f5") == 0)
335 } /* do next dir entry */
337 if (dot
!= 1) e(2); /* Check the entrys */
338 if (dotdot
!= 1) e(3);
344 if (other
!= 0) e(9);
346 subtest
= oldsubtest
;
353 memset(MaxName
, 'a', NAME_MAX
);
354 MaxName
[NAME_MAX
] = '\0';
355 for (i
= 0; i
< PATH_MAX
- 1; i
++) { /* idem path */
359 MaxPath
[PATH_MAX
- 1] = '\0';
361 strcpy(ToLongName
, MaxName
); /* copy them Max to ToLong */
362 strcpy(ToLongPath
, MaxPath
);
364 ToLongName
[NAME_MAX
] = 'a';
365 ToLongName
[NAME_MAX
+ 1] = '\0'; /* extend ToLongName by one too many */
366 ToLongPath
[PATH_MAX
- 1] = '/';
367 ToLongPath
[PATH_MAX
] = '\0'; /* inc ToLongPath by one */
373 int err_num
= errno
; /* Save in case printf clobbers it. */
375 printf("Subtest %d, error %d errno=%d: ", subtest
, n
, errno
);
378 if (errct
++ > MAX_ERROR
) {
379 printf("Too many errors; test aborted\n");
381 system("rm -rf DIR*");
390 System("rm -rf DIR_24");
396 printf("%d errors\n", errct
);