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 (at) us.ibm.com */ 21 /* 06/30/2001 Port to Linux nsharoff (at) 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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