• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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