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