1 /*
2 *
3 * Copyright (c) International Business Machines Corp., 2002
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
13 * the GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20 /* 10/31/2002 Port to LTP robbiew@us.ibm.com */
21 /* 06/30/2001 Port to Linux nsharoff@us.ibm.com */
22
23 /*
24 * NAME
25 * test.c - Test functions for nftw()
26 */
27
28 #include "nftw.h"
29
30 extern int callback(const char *path);
31
32 extern pathdata pathdat[];
33 extern struct list mnem[], badlist[];
34 extern char *dirlist[NDIRLISTENTS], *goodlist[];
35 extern int npathdats, ngoods, nbads, nmnem, visit, s2, next_fd[4];
36
37 extern FILE *temp;
38 /*
39 * void test1A() - tests the assertion:
40 * A call to int nftw(const char *path, int (*fn)(const char *, const
41 * struct stat *, int, struct FTW *), int depth, int flags) shall
42 * recursively descend the directory hierarchy rooted in path until it
43 * has traversed the whole tree, calling the function fn for each object
44 * in the directory tree, and return 0.
45 */
46
test1A(void)47 void test1A(void)
48 {
49 int i, j, ret;
50
51 temp = stderr;
52 #ifdef DEBUG
53 fprintf(temp, "TEST: nftw() succeeds\n");
54 #endif
55
56 visit = 0;
57 if ((ret = nftw("./tmp/data/dirh", test_func1, MAX_FD, 0)) == -1) {
58 perror("ERROR: nftw failed");
59 cleanup_function();
60 fail_exit();
61 }
62
63 if (ret == 999) {
64 cleanup_function();
65 fail_exit();
66 }
67 #ifdef DEBUG
68 fprintf(temp, "TEST: Whole tree traversed\n");
69 #endif
70
71 if (visit != ngoods) {
72 fprintf(temp, "ERROR: Count of objects visited incorrect\n");
73 fprintf(temp, " Expected %d, Received %d\n", ngoods,
74 visit);
75 cleanup_function();
76 fail_exit();
77 }
78
79 for (i = 0; i < visit; i++) {
80 for (j = 0; j < ngoods; j++) {
81 if (strcmp(dirlist[i], goodlist[j]) == 0) {
82 free(dirlist[i]);
83 dirlist[i] = NULL;
84 break;
85 }
86 }
87 }
88
89 for (i = 0; i < visit; i++) {
90 if (dirlist[i] != NULL) {
91 free(dirlist[i]);
92 fprintf(temp, "ERROR: Unexpected visit to %s\n",
93 dirlist[i]);
94 cleanup_function();
95 fail_exit();
96 }
97 }
98 }
99
100 /*
101 * void test2A() - tests the assertion:
102 * A call to int nftw(const char *path, int (*fn)(const char *, const
103 * struct stat *, int, struct FTW *), int depth, int flags) when flags
104 * contains FTW_PHYS shall not traverse symbolic links.
105 */
106
test2A(void)107 void test2A(void)
108 {
109 int i, ret;
110
111 temp = stderr;
112 #ifdef DEBUG
113 fprintf(temp,
114 "TEST: nftw with FTW_PHYS does not follow symbolic links\n");
115 #endif
116
117 visit = 0;
118 if ((ret = nftw("./tmp/data/dirl", test_func1, MAX_FD, FTW_PHYS))
119 == -1) {
120 perror("nftw");
121 cleanup_function();
122 fail_exit();
123 }
124
125 if (ret == 999) {
126 cleanup_function();
127 fail_exit();
128 }
129
130 if (visit != NO_LINK_CNT) {
131 fprintf(temp,
132 "ERROR: Expected %d files to be visited. nftw() visited %d\n",
133 NO_LINK_CNT, visit);
134 cleanup_function();
135 fail_exit();
136 }
137
138 for (i = 0; i < visit; i++) {
139 if (dirlist[i] != NULL)
140 free(dirlist[i]);
141 }
142 }
143
144 /*
145 * void test3A() - tests the assertion:
146 * A call to int nftw(const char *path, int (*fn)(const char *, const
147 * struct stat *, int, struct FTW *), int depth, int flags) when flags
148 * does not contain FTW_PHYS shall follow links instead of reporting
149 * them and shall not report the same file twice.
150 */
151
test3A(void)152 void test3A(void)
153 {
154 int ret;
155
156 #ifdef DEBUG
157 fprintf(temp, "TEST: nftw without FTW_PHYS follows symbolic links\n");
158 #endif
159
160 visit = 0;
161
162 if ((ret = nftw("./tmp/data/dirl", test_func3, MAX_FD, 0)) == -1) {
163 perror("nftw");
164 cleanup_function();
165 fail_exit();
166 }
167 if (ret == 999) {
168 cleanup_function();
169 fail_exit();
170 }
171
172 if (visit != LINK_CNT - 1) {
173 fprintf(temp,
174 "ERROR: Expected %d files to be visited. nftw() visited %d\n",
175 LINK_CNT - 1, visit);
176 cleanup_function();
177 fail_exit();
178 }
179 }
180
181 /*
182 * void test4A() - tests the assertion:
183 * A call to int nftw(const char *path, int (*fn)(const char *, const
184 * struct stat *, int, struct FTW *), int depth, int flags) when flags
185 * contains FTW_DEPTH shall report all files in a directory before
186 * reporting the directory.
187 */
188
test4A(void)189 void test4A(void)
190 {
191 char path[] = "./tmp/data/d777";
192 int ret_val;
193
194 #ifdef DEBUG
195 fprintf(temp, "TEST: Verify traversal with FTW_DEPTH set\n");
196 #endif
197
198 visit = 0;
199 if ((ret_val = nftw(path, test_func4, MAX_FD, FTW_DEPTH)) == -1) {
200 perror("nftw");
201 cleanup_function();
202 fail_exit();
203 }
204 if (ret_val != 999) {
205 fprintf(temp, "ERROR: %s never visited\n", path);
206 cleanup_function();
207 fail_exit();
208 }
209
210 if (visit != 2) {
211 fprintf(temp, "ERROR: Visited directory before contents\n");
212 cleanup_function();
213 fail_exit();
214 }
215 }
216
217 /*
218 * void test5A() - tests the assertion:
219 * A call to int nftw(const char *path, int (*fn)(const char *, const
220 * struct stat *, int, struct FTW *), int depth, int flags) when flags
221 * does not contain FTW_DEPTH shall report a directory before reporting
222 * the files in that directory.
223 */
224
test5A(void)225 void test5A(void)
226 {
227 char path[] = "./tmp/data/d777";
228 int ret_val;
229
230 #ifdef DEBUG
231 fprintf(temp, "TEST: Verify traversal without FTW_DEPTH set\n");
232 #endif
233
234 visit = 0;
235 if ((ret_val = nftw(path, test_func4, MAX_FD, 0)) == -1) {
236 perror("nftw");
237 cleanup_function();
238 fail_exit();
239 }
240 if (ret_val != 999) {
241 fprintf(temp, "ERROR: %s never visited\n", path);
242 cleanup_function();
243 fail_exit();
244 }
245
246 if (visit != 1) {
247 fprintf(temp, "ERROR: Visited contents before directory\n");
248 cleanup_function();
249 fail_exit();
250 }
251 }
252
253 /*
254 * void test6A() - tests the assertion:
255 * A call to int nftw(const char *path, int (*fn)(const char *, const
256 * struct stat *, int, struct FTW *), int depth, int flags) when flags
257 * contains FTW_CHDIR shall change the current working directory to each
258 * directory as it reports files in that directory.
259 */
260
test6A(void)261 void test6A(void)
262 {
263 char path[PATH_MAX + NAME_MAX];
264 int ret_val;
265
266 if (getcwd(path, sizeof(path)) == NULL) {
267 perror("getcwd");
268 cleanup_function();
269 fail_exit();
270 }
271 (void)strcat(path, "/tmp/data/dirh");
272
273 #ifdef DEBUG
274 fprintf(temp,
275 "TEST: nftw with FTW_CHDIR changes to each dir before reporting files in it\n");
276 #endif
277
278 ret_val = nftw(path, test_func5, MAX_FD, FTW_CHDIR);
279 if (ret_val == -1) {
280 perror("nftw");
281 cleanup_function();
282 fail_exit();
283 }
284 if ((ret_val == 998) || (ret_val == 999)) {
285 cleanup_function();
286 fail_exit();
287 }
288 }
289
290 /*
291 * void test7A() - tests the assertion:
292 * A call to int nftw(const char *path, int (*fn)(const char *, const
293 * struct stat *, int, struct FTW *), int depth, int flags) shall pass
294 * the path-name of the current object as the first argument of the
295 * function fn.
296 */
297
test7A(void)298 void test7A(void)
299 {
300 int ret;
301
302 #ifdef DEBUG
303 fprintf(temp, "TEST: nftw passes pathname as first argument to fn()\n");
304 #endif
305
306 if ((ret = nftw("./tmp/data/dirg", test_func7, MAX_FD, 0)) == -1) {
307 perror("nftw");
308 cleanup_function();
309 fail_exit();
310 }
311
312 if (ret == 999) {
313 cleanup_function();
314 fail_exit();
315 }
316 }
317
318 /*
319 * void test8A() - tests the assertion:
320 * A call to int nftw(const char *path, int (*fn)(const char *, const
321 * struct stat *, int, struct FTW *), int depth, int flags) shall pass a
322 * pointer to a stat structure containing information about the current
323 * object as the second argument to fn.
324 */
325
test8A(void)326 void test8A(void)
327 {
328 int ret;
329
330 #ifdef DEBUG
331 fprintf(temp,
332 "TEST: nftw passes stat struct as second argument to fn()\n");
333 #endif
334
335 if ((ret = nftw("./tmp/data/dirg", test_func8, MAX_FD, 0)) == -1) {
336 perror("nftw");
337 cleanup_function();
338 fail_exit();
339 }
340
341 if (ret == 999) {
342 cleanup_function();
343 fail_exit();
344 }
345 }
346
347 /*
348 * void test9A() - tests the assertion:
349 * A call to int nftw(const char *path, int (*fn)(const char *, const
350 * struct stat *, int, struct FTW *), int depth, int flags) shall pass
351 * FTW_F as the third argument of the function fn when the object is a
352 * file
353 */
354
test9A(void)355 void test9A(void)
356 {
357 int ret;
358
359 #ifdef DEBUG
360 fprintf(temp,
361 "TEST: nftw passes FTW_F as third arg to fn() for files\n");
362 #endif
363
364 if ((ret = nftw("./tmp/data/dirg", test_func9, MAX_FD, FTW_PHYS)) == -1) {
365 perror("nftw");
366 cleanup_function();
367 fail_exit();
368 }
369
370 if (ret == 999) {
371 cleanup_function();
372 fail_exit();
373 }
374 }
375
376 /*
377 * void test10A() - tests the assertion:
378 * A call to int nftw(const char *path, int (*fn)(const char *, const
379 * struct stat *, int, struct FTW *), int depth, int flags) shall pass
380 * FTW_D as the third argument of the function fn when the object is a
381 * directory.
382 */
383
test10A(void)384 void test10A(void)
385 {
386 int ret;
387
388 #ifdef DEBUG
389 fprintf(temp,
390 "TEST: nftw passes FTW_D as third arg to fn() when file is directory\n");
391 #endif
392
393 if ((ret = nftw("./tmp/data/dirg", test_func10, MAX_FD,
394 FTW_PHYS)) == -1) {
395 perror("nftw");
396 cleanup_function();
397 fail_exit();
398 }
399
400 if (ret == 999) {
401 cleanup_function();
402 fail_exit();
403 }
404 }
405
406 /*
407 * void test11A() - tests the assertion:
408 * A call to int nftw(const char *path, int (*fn)(const char *, const
409 * struct stat *, int, struct FTW *), int depth, int flags) shall pass
410 * FTW_DP as the third argument of the function fn when the object is a
411 * directory and subdirectories have been visited.
412 */
413
test11A(void)414 void test11A(void)
415 {
416 int i, ret;
417
418 for (i = 0; i < nbads; i++)
419 if (badlist[i].i == FTW_D)
420 badlist[i].i = FTW_DP;
421
422 #ifdef DEBUG
423 fprintf(temp,
424 "TEST: nftw passes FTW_DP when file is directory and subdirs already visited\n");
425 #endif
426
427 if ((ret = nftw("./tmp/data/dirg", test_func11, MAX_FD, FTW_DEPTH |
428 FTW_PHYS)) == -1) {
429 perror("nftw");
430 cleanup_function();
431 fail_exit();
432 }
433
434 if (ret == 999) {
435 cleanup_function();
436 fail_exit();
437 }
438 }
439
440 /*
441 * void test12A() - tests the assertion:
442 * A call to int nftw(const char *path, int (*fn)(const char *, const
443 * struct stat *, int, struct FTW *), int depth, int flags) shall pass
444 * FTW_SL as the third argument of the function fn when the object is a
445 * symbolic link.
446 */
447
test12A(void)448 void test12A(void)
449 {
450 int ret;
451
452 #ifdef DEBUG
453 fprintf(temp,
454 "TEST: nftw wth FTW_PHYS passes FTW_SL when file is symlink\n");
455 #endif
456
457 if ((ret = nftw("./tmp/data/dirg", test_func12, MAX_FD,
458 FTW_PHYS)) == -1) {
459 perror("nftw");
460 cleanup_function();
461 fail_exit();
462 }
463
464 if (ret == 999) {
465 cleanup_function();
466 fail_exit();
467 }
468 }
469
470 /*
471 * void test13A() - tests the assertion:
472 * A call to int nftw(const char *path, int (*fn)(const char *, const
473 * struct stat *, int, struct FTW *), int depth, int flags) shall pass
474 * FTW_SLN as the third argument of the function fn when the object is a
475 * symbolic link that does not name an existing file.
476 */
477
test13A(void)478 void test13A(void)
479 {
480 int i, ret;
481
482 if (unlink("./tmp/byebye") == -1) {
483 perror("unlink");
484 cleanup_function();
485 fail_exit();
486 }
487
488 for (i = 0; i < nbads; i++)
489 if (badlist[i].i == FTW_SL)
490 badlist[i].i = FTW_SLN;
491
492 #ifdef DEBUG
493 fprintf(temp, "TEST: nftw with FTW_PHYS passes FTW_SLN when file");
494 fprintf(temp, " is symlink pointing \n to non-existent file\n");
495 #endif
496
497 if ((ret = nftw("./tmp/data/dirg", test_func13, MAX_FD,
498 FTW_PHYS)) == -1) {
499 perror("nftw");
500 cleanup_function();
501 fail_exit();
502 }
503
504 if (ret == 999) {
505 cleanup_function();
506 fail_exit();
507 }
508 }
509
510 /*
511 * void test14A() - tests the assertion:
512 * A call to int nftw(const char *path, int (*fn)(const char *, const
513 * struct stat *, int, struct FTW *), int depth, int flags) shall pass
514 * FTW_DNR as the third argument of the function fn when the object is a
515 * directory that cannot be read.
516 */
517
test14A(void)518 void test14A(void)
519 {
520 int ret;
521
522 #ifdef DEBUG
523 fprintf(temp,
524 "TEST: nftw passes FTW_DNR when file is directory that cannot be read\n");
525 #endif
526
527 if ((ret = nftw("./tmp/data/d333", test_func14, MAX_FD, 0)) == -1) {
528 perror("nftw");
529 cleanup_function();
530 fail_exit();
531 }
532
533 if (ret == 999) {
534 cleanup_function();
535 fail_exit();
536 }
537 }
538
539 /*
540 * void test15A() - tests the assertion:
541 * A call to int nftw(const char *path, int (*fn)(const char *, const
542 * struct stat *, int, struct FTW *), int depth, int flags) shall pass
543 * FTW_NS as the third argument of the function fn when stat() failed on
544 * the object because of lack of appropriate permission.
545 */
546
test15A(void)547 void test15A(void)
548 {
549 int ret;
550
551 #ifdef DEBUG
552 fprintf(temp,
553 "TEST: nftw(path, fn, depth, FTW_PHYS) passes FTW_NS when dir unsearchable\n");
554 #endif
555
556 if ((ret =
557 nftw("./tmp/data/d666", test_func15, MAX_FD, FTW_PHYS)) == -1) {
558 perror("nftw");
559 cleanup_function();
560 fail_exit();
561 }
562
563 if (ret == 999) {
564 cleanup_function();
565 fail_exit();
566 }
567 }
568
569 /*
570 * void test16A() - tests the assertion:
571 * A call to int nftw(const char *path, int (*fn)(const char *, const
572 * struct stat *, int, struct FTW *), int depth, int flags) shall pass a
573 * structure which contains the offset into the pathname of the object
574 * and the depth relative to the root of the walk starting from 0 as the
575 * fourth argument of the function fn.
576 */
577
test16A(void)578 void test16A(void)
579 {
580 char path[PATH_MAX + NAME_MAX];
581 char orig[PATH_MAX];
582
583 if (getcwd(orig, sizeof(orig)) == NULL) {
584 perror("getcwd on original wd");
585 cleanup_function();
586 fail_exit();
587 }
588
589 strcpy(path, orig);
590 (void)strcat(path, "/tmp/data/dirg");
591
592 #ifdef DEBUG
593 fprintf(temp, "TEST: nftw with absolute pathname %s\n", path);
594 #endif
595
596 if ((s2 = nftw(path, test_func16, MAX_FD, 0)) == -1) {
597 perror("nftw");
598 cleanup_function();
599 fail_exit();
600 }
601 if (s2 == 999) {
602 cleanup_function();
603 fail_exit();
604 }
605
606 (void)strcpy(path, "./tmp/data/dirg");
607
608 #ifdef DEBUG
609 fprintf(temp, "TEST: nftw with relative pathname %s\n", path);
610 #endif
611
612 if ((s2 = nftw(path, test_func16, MAX_FD, 0)) == -1) {
613 perror("nftw");
614 cleanup_function();
615 fail_exit();
616 }
617
618 if (s2 == 999) {
619 cleanup_function();
620 fail_exit();
621 }
622 }
623
624 /*
625 * void test17A() - tests the assertion:
626 * A call to int nftw(const char *path, int (*fn)(const char *, const
627 * struct stat *, int, struct FTW *), int depth, int flags) shall pass
628 * FTW_SL as the third argument to the function fn if and only if the
629 * FTW_PHYS flag is included in flags.
630 */
631
test17A(void)632 void test17A(void)
633 {
634 int ret;
635
636 visit = 0;
637
638 #ifdef DEBUG
639 fprintf(temp, "TEST: nftw with FTW_PHYS passes FTW_SL for symlink\n");
640 #endif
641
642 if ((ret =
643 nftw("./tmp/data/dirl", test_func17, MAX_FD, FTW_PHYS)) == -1) {
644 perror("nftw");
645 cleanup_function();
646 fail_exit();
647 }
648 if (ret != 999) {
649 fprintf(temp, "ERROR: nftw() failed to find symbolic link\n");
650 cleanup_function();
651 fail_exit();
652 }
653
654 visit = 0;
655
656 #ifdef DEBUG
657 fprintf(temp,
658 "TEST: nftw without FTW_PHYS does not pass FTW_SL for symlink\n");
659 #endif
660
661 if ((ret = nftw("./tmp/data/dirl", test_func17, MAX_FD, 0)) == -1) {
662 perror("nftw");
663 cleanup_function();
664 fail_exit();
665 }
666 if (ret == 999) {
667 fprintf(temp, "ERROR: nftw() found symbolic link\n");
668 cleanup_function();
669 fail_exit();
670 }
671 }
672
673 /*
674 * void test18A() - tests the assertion:
675 * A call to int nftw(const char *path, int (*fn)(const char *, const
676 * struct stat *, int, struct FTW *), int depth, int flags) shall pass
677 * FTW_SLN as the third argument to the function fn if and only if the
678 * FTW_PHYS flag is not included in flags.
679 */
680
test18A(void)681 void test18A(void)
682 {
683 int ret;
684
685 unlink("./tmp/byebye");
686
687 visit = 0;
688
689 #ifdef DEBUG
690 fprintf(temp, "TEST: nftw with FTW_PHYS does not pass FTW_SLN\n");
691 #endif
692
693 if ((ret = nftw("./tmp/data/dirg", test_func18, MAX_FD,
694 FTW_PHYS)) == -1) {
695 perror("nftw");
696 cleanup_function();
697 fail_exit();
698 }
699 if (ret == 999) {
700 fprintf(temp, "ERROR: nftw() passed FTW_SLN\n");
701 cleanup_function();
702 fail_exit();
703 }
704
705 visit = 0;
706
707 #ifdef DEBUG
708 fprintf(temp, "TEST: nftw without FTW_PHYS passes FTW_SLN\n");
709 #endif
710
711 if ((ret = nftw("./tmp/data/dirg", test_func18, MAX_FD, 0)) == -1) {
712 perror("nftw");
713 cleanup_function();
714 fail_exit();
715 }
716
717 if (visit == 1) {
718 if (ret == 999) {
719 /* Test is passed */
720 return;
721 } else {
722 fprintf(temp, "ERROR: nftw passed FTW_SLN but did");
723 fprintf(temp, "not return value returned by fn()\n");
724 cleanup_function();
725 fail_exit();
726 }
727 } else {
728 fprintf(temp, "ERROR: nftw() did not pass FTW_SLN\n");
729 cleanup_function();
730 fail_exit();
731 }
732 }
733
734 /*
735 * void test19A() - tests the assertion:
736 * On a call to int nftw(const char *path, int (*fn)(const char *, const
737 * struct stat *, int, struct FTW *), int depth, int flags) when the
738 * third argument passed to the function fn is FTW_DNR then the
739 * descendants of the directory shall not be processed.
740 */
741
test19A(void)742 void test19A(void)
743 {
744 int ret_val;
745
746 #ifdef DEBUG
747 fprintf(temp,
748 "TEST: Can not traverse directory with no read permission\n");
749 #endif
750
751 visit = 0;
752
753 ret_val = nftw("./tmp/data/d333", test_func19, MAX_FD, 0);
754 if (ret_val == -1) {
755 perror("nftw");
756 cleanup_function();
757 fail_exit();
758 }
759
760 if (ret_val == 999) {
761 cleanup_function();
762 fail_exit();
763 }
764 #ifdef DEBUG
765 fprintf(temp, "TEST: fn only be called once\n");
766 #endif
767
768 if (visit != 1) {
769 fprintf(temp, "ERROR: %s",
770 "Directory without read permission allows traversing\n");
771 fprintf(temp, " Visited %d files\n", visit);
772 cleanup_function();
773 fail_exit();
774 }
775 }
776
777 /*
778 * void test20A() - tests the assertion:
779 * A call to int nftw(const char *path, int (*fn)(const char *, const
780 * struct stat *, int, struct FTW *), int depth, int flags) shall close
781 * any file descriptors or directory streams used to traverse the
782 * directory tree.
783 */
784
test20A(void)785 void test20A(void)
786 {
787 int fd, nfd;
788
789 #ifdef DEBUG
790 fprintf(temp, "TEST: File descriptors used in traversal are closed\n");
791 #endif
792
793 if ((fd = open("./tmp/data/dirh", O_RDONLY)) == -1) {
794 perror("close");
795 cleanup_function();
796 fail_exit();
797 }
798
799 if (close(fd) == -1) {
800 perror("close");
801 cleanup_function();
802 fail_exit();
803 }
804
805 if (nftw("./tmp/data/dirh", test_func20, 1, 0) == -1) {
806 perror("nftw");
807 cleanup_function();
808 fail_exit();
809 }
810
811 if ((nfd = open("./tmp/data/dirh", O_RDONLY)) == -1) {
812 perror("open");
813 cleanup_function();
814 fail_exit();
815 }
816
817 if (nfd != fd) {
818 fprintf(temp, "ERROR: %s,fd == %d ofd = %d",
819 "nftw did not close all file descriptors used in traversal\n",
820 nfd, fd);
821 cleanup_function();
822 fail_exit();
823 }
824
825 if (close(nfd) == -1) {
826 perror("close");
827 cleanup_function();
828 fail_exit();
829 }
830 }
831
832 /*
833 * void test21A() - tests the assertion:
834 * On a call to int nftw(const char *path, int (*fn)(const char *, const
835 * struct stat *, int, struct FTW *), int depth, int flags) shall
836 * be the maximum number of file descriptors used for the search.
837 */
838
test21A(void)839 void test21A(void)
840 {
841 char path[] = "./tmp/data/dirh";
842 int ret_val;
843
844 #ifdef DEBUG
845 fprintf(temp,
846 "TEST: No more than depth file descriptors used in traversal\n");
847 #endif
848
849 /*this is the fd we expect if 0 are used */
850 if ((next_fd[0] = open(path, O_RDONLY)) == -1) {
851 perror("open next_fd[0]");
852 cleanup_function();
853 fail_exit();
854 }
855
856 /*this is the fd we expect if 1 is used */
857 if ((next_fd[1] = open(path, O_RDONLY)) == -1) {
858 perror("open next_fd[1]");
859 cleanup_function();
860 fail_exit();
861 }
862
863 if (close(next_fd[0]) == -1) {
864 perror("close next_fd[0]");
865 cleanup_function();
866 fail_exit();
867 }
868
869 if (close(next_fd[1]) == -1) {
870 perror("close next_fd[1]");
871 cleanup_function();
872 fail_exit();
873 }
874
875 visit = 0;
876 ret_val = nftw(path, test_func21, 1, 0);
877 if (ret_val == -1) {
878 perror("nftw");
879 cleanup_function();
880 fail_exit();
881 }
882
883 if (ret_val == 999) {
884 cleanup_function();
885 fail_exit();
886 }
887 }
888
889 /*
890 * void test22A() - tests the assertion:
891 * A call to int nftw(const char *path, int (*fn)(const char *, const
892 * struct stat *, int, struct FTW *), int depth, int flags) shall use at
893 * most one file descriptor for each directory level.
894 */
895
test22A(void)896 void test22A(void)
897 {
898 char path[] = "./tmp/data/dirh";
899 int ret_val, i;
900
901 for (i = 0; i < 4; i++) {
902 if ((next_fd[i] = open(path, O_RDONLY)) == -1) {
903 perror("open");
904 cleanup_function();
905 fail_exit();
906 }
907 }
908
909 for (i = 0; i < 4; i++) {
910 if (close(next_fd[i]) == -1) {
911 perror("close");
912 cleanup_function();
913 fail_exit();
914 }
915 }
916
917 visit = 0;
918
919 #ifdef DEBUG
920 fprintf(temp,
921 "TEST: No more than 1 fd per level is used in traversal\n");
922 #endif
923
924 ret_val = nftw(path, test_func22, MAX_FD, 0);
925
926 if (ret_val == -1) {
927 perror("nftw");
928 cleanup_function();
929 fail_exit();
930 }
931
932 if (ret_val == 999) {
933 cleanup_function();
934 fail_exit();
935 }
936 }
937
938 /*
939 * void test23A() - tests the assertion:
940 * A call to int nftw(const char *path, int (*fn)(const char *, const
941 * struct stat *, int, struct FTW *), int depth, int flags) when the
942 * function fn returns a non-zero value shall stop and return the value
943 * returned by fn.
944 */
945
test23A(void)946 void test23A(void)
947 {
948 int ret;
949
950 visit = 0;
951
952 #ifdef DEBUG
953 fprintf(temp,
954 "TEST: The function nftw should return with value set by fn\n");
955 #endif
956
957 if ((ret =
958 nftw("./tmp/data/dirh", test_func23, MAX_FD, FTW_PHYS)) == -1) {
959 perror("nftw");
960 cleanup_function();
961 fail_exit();
962 }
963
964 if (ret != 999) {
965 fprintf(temp,
966 "ERROR: nftw did not return value returned by fn()\n");
967 cleanup_function();
968 fail_exit();
969 }
970 if (visit != 4) {
971 fprintf(temp,
972 "ERROR: nftw() did not return immediately on non-zero fn() return\n");
973 cleanup_function();
974 fail_exit();
975 }
976 }
977
978 /*
979 * void test24A() - tests the assertion:
980 * ENAMETOOLONG in errno and return -1 on a call to int nftw(const char
981 * *path, int (*fn)(const char *, const struct stat *, int, struct FTW
982 * *), int depth, int flags) when the length of path exceeds PATH_MAX.
983 */
984
test24A(void)985 void test24A(void)
986 {
987 test_ENAMETOOLONG_path("nftw", callback, -1);
988 }
989
990 /*
991 * void test25A() - tests the assertion:
992 * ENAMETOOLONG in errno and return -1 on a call to int nftw(const char
993 * *path, int (*fn)(const char *, const struct stat *, int, struct FTW
994 * *), int depth, int flags) when a component of path exceeds NAME_MAX.
995 */
996
test25A(void)997 void test25A(void)
998 {
999 test_ENAMETOOLONG_name("nftw", callback, -1);
1000 }
1001
1002 /*
1003 * void test26A() - tests the assertion:
1004 * ENOENT in errno and return -1 on a call to int nftw(const char *path,
1005 * int (*fn)(const char *, const struct stat *, int, struct FTW *), int
1006 * depth, int flags) when path points to a file which does not exist.
1007 */
1008
test26A(void)1009 void test26A(void)
1010 {
1011 #ifdef DEBUG
1012 fprintf(temp, "TEST: [ENOENT] && -1 returned by nftw\n");
1013 #endif
1014
1015 test_ENOENT_nofile("nftw", callback, -1);
1016 }
1017
1018 /*
1019 * void test27A() - tests the assertion:
1020 * ENOENT in errno and return -1 on a call to int nftw(const char *path,
1021 * int (*fn)(const char *, const struct stat *, int, struct FTW *), int
1022 * depth, int flags) when path points to an empty string.
1023 */
1024
test27A(void)1025 void test27A(void)
1026 {
1027 #ifdef DEBUG
1028 fprintf(temp, "TEST: The function nftw should return with a -1\n");
1029 #endif
1030
1031 test_ENOENT_empty("nftw", callback, -1);
1032 }
1033
1034 /*
1035 * void test28A() - tests the assertion:
1036 * ENOTDIR in errno and return -1 on a call to int nftw(const char
1037 * *path, int (*fn)(const char *, const struct stat *, int, struct FTW
1038 * *), int depth, int flags) when path is not a directory.
1039 */
1040
test28A(void)1041 void test28A(void)
1042 {
1043 #ifdef DEBUG
1044 fprintf(temp, "TEST: [ENOTDIR] && -1 returned by nftw\n");
1045 #endif
1046
1047 test_ENOTDIR("nftw", callback, -1);
1048 }
1049
1050 /*
1051 * void test29A() - tests the assertion:
1052 * EACCES in errno and return -1 on a call to int nftw(const char *path,
1053 * int (*fn)(const char *, const struct stat *, int, struct FTW *), int
1054 * depth, int flags) when search permission is denied for any component
1055 * of path.
1056 */
1057
test29A(void)1058 void test29A(void)
1059 {
1060 if (chmod("./tmp/data/d333", (mode_t) S_IRUSR) == -1) {
1061 perror("chmod");
1062 cleanup_function();
1063 fail_exit();
1064 }
1065 #ifdef DEBUG
1066 fprintf(temp, "TEST: [EACCES] && -1 returned by nftw\n");
1067 #endif
1068
1069 test_ENOTDIR("nftw", callback, -1);
1070 }
1071
1072 /*
1073 * void test30A() - tests the assertion:
1074 * EACCES in errno and return -1 on a call to int nftw(const char *path,
1075 * int (*fn)(const char *, const struct stat *, int, struct FTW *), int
1076 * depth, int flags) when read permission is denied for path.
1077 */
1078
test30A(void)1079 void test30A(void)
1080 {
1081 if (chmod("./tmp/data/d333", (mode_t) S_IXUSR) == -1) {
1082 perror("chmod");
1083 cleanup_function();
1084 fail_exit();
1085 }
1086 #ifdef DEBUG
1087 fprintf(temp, "TEST: [EACCES] && -1 returned by nftw\n");
1088 #endif
1089 test_ENOTDIR("nftw", callback, -1);
1090 }
1091