| /* |
| * |
| * Copyright (c) International Business Machines Corp., 2002 |
| * |
| * This program is free software; you can redistribute it and/or modify |
| * it under the terms of the GNU General Public License as published by |
| * the Free Software Foundation; either version 2 of the License, or |
| * (at your option) any later version. |
| * |
| * This program is distributed in the hope that it will be useful, |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See |
| * the GNU General Public License for more details. |
| * |
| * You should have received a copy of the GNU General Public License |
| * along with this program; if not, write to the Free Software |
| * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
| */ |
| |
| /* 10/31/2002 Port to LTP robbiew@us.ibm.com */ |
| /* 06/30/2001 Port to Linux nsharoff@us.ibm.com */ |
| |
| /* |
| * NAME |
| * test.c - Test functions for nftw() |
| */ |
| |
| #define _USC_LIB_ |
| |
| #include "nftw.h" |
| |
| extern int callback(const char *path); |
| |
| extern pathdata pathdat[]; |
| extern struct list mnem[], badlist[]; |
| extern char *dirlist[NDIRLISTENTS], *goodlist[]; |
| extern int npathdats, ngoods, nbads, nmnem, visit, s2, next_fd[4]; |
| |
| extern FILE *temp; |
| /* |
| * void test1A() - tests the assertion: |
| * A call to int nftw(const char *path, int (*fn)(const char *, const |
| * struct stat *, int, struct FTW *), int depth, int flags) shall |
| * recursively descend the directory hierarchy rooted in path until it |
| * has traversed the whole tree, calling the function fn for each object |
| * in the directory tree, and return 0. |
| */ |
| |
| void |
| test1A(void) |
| { |
| int i, j, ret; |
| |
| temp = stderr; |
| #ifdef DEBUG |
| fprintf(temp, "TEST: nftw() succeeds\n"); |
| #endif |
| |
| visit = 0; |
| if((ret = nftw("./tmp/data/dirh", test_func1, MAX_FD,0 )) == -1) { |
| perror("ERROR: nftw failed"); |
| cleanup_function(); |
| fail_exit(); |
| } |
| |
| if(ret == 999) { |
| cleanup_function(); |
| fail_exit(); |
| } |
| |
| #ifdef DEBUG |
| fprintf(temp, "TEST: Whole tree traversed\n"); |
| #endif |
| |
| if (visit != ngoods) { |
| fprintf(temp, "ERROR: Count of objects visited incorrect\n"); |
| fprintf(temp, " Expected %d, Received %d\n", ngoods, visit); |
| cleanup_function(); |
| fail_exit(); |
| } |
| |
| for (i = 0; i < visit; i++) { |
| for (j = 0; j < ngoods; j++) { |
| if (strcmp(dirlist[i], goodlist[j]) == 0) { |
| free(dirlist[i]); |
| dirlist[i] = (char *)NULL; |
| break; |
| } |
| } |
| } |
| |
| for (i = 0; i < visit; i++) { |
| if (dirlist[i] != (char *)NULL) { |
| free(dirlist[i]); |
| fprintf(temp, "ERROR: Unexpected visit to %s\n", dirlist[i]); |
| cleanup_function(); |
| fail_exit(); |
| } |
| } |
| } |
| |
| |
| |
| /* |
| * void test2A() - tests the assertion: |
| * A call to int nftw(const char *path, int (*fn)(const char *, const |
| * struct stat *, int, struct FTW *), int depth, int flags) when flags |
| * contains FTW_PHYS shall not traverse symbolic links. |
| */ |
| |
| void |
| test2A(void) |
| { |
| int i, ret; |
| |
| temp = stderr; |
| #ifdef DEBUG |
| fprintf(temp, "TEST: nftw with FTW_PHYS does not follow symbolic links\n"); |
| #endif |
| |
| visit = 0; |
| if((ret = nftw("./tmp/data/dirl", test_func1, MAX_FD, FTW_PHYS)) |
| == -1) { |
| perror("nftw"); |
| cleanup_function(); |
| fail_exit(); |
| } |
| |
| if(ret == 999) { |
| cleanup_function(); |
| fail_exit(); |
| } |
| |
| if (visit != NO_LINK_CNT) |
| { |
| fprintf(temp, "ERROR: Expected %d files to be visited. nftw() visited %d\n", NO_LINK_CNT, visit); |
| cleanup_function(); |
| fail_exit(); |
| } |
| |
| for (i = 0; i < visit; i++) { |
| if (dirlist[i] != (char *)NULL) |
| free(dirlist[i]); |
| } |
| } |
| |
| |
| /* |
| * void test3A() - tests the assertion: |
| * A call to int nftw(const char *path, int (*fn)(const char *, const |
| * struct stat *, int, struct FTW *), int depth, int flags) when flags |
| * does not contain FTW_PHYS shall follow links instead of reporting |
| * them and shall not report the same file twice. |
| */ |
| |
| void |
| test3A(void) |
| { |
| int ret; |
| |
| #ifdef DEBUG |
| fprintf(temp, "TEST: nftw without FTW_PHYS follows symbolic links\n"); |
| #endif |
| |
| visit = 0; |
| |
| if((ret = nftw("./tmp/data/dirl", test_func3, MAX_FD, 0)) == -1) { |
| perror("nftw"); |
| cleanup_function(); |
| fail_exit(); |
| } |
| if(ret == 999) { |
| cleanup_function(); |
| fail_exit(); |
| } |
| |
| if (visit != LINK_CNT-1) |
| { |
| fprintf(temp, "ERROR: Expected %d files to be visited. nftw() visited %d\n", LINK_CNT-1, visit); |
| cleanup_function(); |
| fail_exit(); |
| } |
| } |
| |
| |
| /* |
| * void test4A() - tests the assertion: |
| * A call to int nftw(const char *path, int (*fn)(const char *, const |
| * struct stat *, int, struct FTW *), int depth, int flags) when flags |
| * contains FTW_DEPTH shall report all files in a directory before |
| * reporting the directory. |
| */ |
| |
| void |
| test4A(void) |
| { |
| char path[] = "./tmp/data/d777"; |
| int ret_val; |
| |
| #ifdef DEBUG |
| fprintf(temp, "TEST: Verify traversal with FTW_DEPTH set\n"); |
| #endif |
| |
| visit = 0; |
| if((ret_val = nftw(path, test_func4, MAX_FD, FTW_DEPTH)) == -1) { |
| perror("nftw"); |
| cleanup_function(); |
| fail_exit(); |
| } |
| if(ret_val != 999) { |
| fprintf(temp, "ERROR: %s never visited\n", path); |
| cleanup_function(); |
| fail_exit(); |
| } |
| |
| if (visit != 2) { |
| fprintf(temp, "ERROR: Visited directory before contents\n"); |
| cleanup_function(); |
| fail_exit(); |
| } |
| } |
| |
| |
| /* |
| * void test5A() - tests the assertion: |
| * A call to int nftw(const char *path, int (*fn)(const char *, const |
| * struct stat *, int, struct FTW *), int depth, int flags) when flags |
| * does not contain FTW_DEPTH shall report a directory before reporting |
| * the files in that directory. |
| */ |
| |
| void |
| test5A(void) |
| { |
| char path[] = "./tmp/data/d777"; |
| int ret_val; |
| |
| #ifdef DEBUG |
| fprintf(temp, "TEST: Verify traversal without FTW_DEPTH set\n"); |
| #endif |
| |
| visit = 0; |
| if((ret_val = nftw(path, test_func4, MAX_FD, 0)) == -1) { |
| perror("nftw"); |
| cleanup_function(); |
| fail_exit(); |
| } |
| if(ret_val != 999) { |
| fprintf(temp, "ERROR: %s never visited\n", path); |
| cleanup_function(); |
| fail_exit(); |
| } |
| |
| if (visit != 1) |
| { |
| fprintf(temp, "ERROR: Visited contents before directory\n"); |
| cleanup_function(); |
| fail_exit(); |
| } |
| } |
| |
| |
| /* |
| * void test6A() - tests the assertion: |
| * A call to int nftw(const char *path, int (*fn)(const char *, const |
| * struct stat *, int, struct FTW *), int depth, int flags) when flags |
| * contains FTW_CHDIR shall change the current working directory to each |
| * directory as it reports files in that directory. |
| */ |
| |
| void |
| test6A(void) |
| { |
| char path[PATH_MAX + NAME_MAX]; |
| int ret_val; |
| |
| if(getcwd(path, sizeof(path)) == NULL) { |
| perror("getcwd"); |
| cleanup_function(); |
| fail_exit(); |
| } |
| (void)strcat(path, "/tmp/data/dirh"); |
| |
| #ifdef DEBUG |
| fprintf(temp, "TEST: nftw with FTW_CHDIR changes to each dir before reporting files in it\n"); |
| #endif |
| |
| ret_val = nftw(path, test_func5, MAX_FD, FTW_CHDIR); |
| if (ret_val == -1) { |
| perror("nftw"); |
| cleanup_function(); |
| fail_exit(); |
| } |
| if ((ret_val == 998) || (ret_val == 999)) { |
| cleanup_function(); |
| fail_exit(); |
| } |
| } |
| |
| |
| /* |
| * void test7A() - tests the assertion: |
| * A call to int nftw(const char *path, int (*fn)(const char *, const |
| * struct stat *, int, struct FTW *), int depth, int flags) shall pass |
| * the path-name of the current object as the first argument of the |
| * function fn. |
| */ |
| |
| void |
| test7A(void) |
| { |
| int ret; |
| |
| #ifdef DEBUG |
| fprintf(temp, "TEST: nftw passes pathname as first argument to fn()\n"); |
| #endif |
| |
| if((ret = nftw("./tmp/data/dirg", test_func7, MAX_FD, 0)) == -1) { |
| perror("nftw"); |
| cleanup_function(); |
| fail_exit(); |
| } |
| |
| if (ret == 999) { |
| cleanup_function(); |
| fail_exit(); |
| } |
| } |
| |
| |
| /* |
| * void test8A() - tests the assertion: |
| * A call to int nftw(const char *path, int (*fn)(const char *, const |
| * struct stat *, int, struct FTW *), int depth, int flags) shall pass a |
| * pointer to a stat structure containing information about the current |
| * object as the second argument to fn. |
| */ |
| |
| void |
| test8A(void) |
| { |
| int ret; |
| |
| #ifdef DEBUG |
| fprintf(temp, "TEST: nftw passes stat struct as second argument to fn()\n"); |
| #endif |
| |
| if((ret = nftw("./tmp/data/dirg", test_func8, MAX_FD, 0)) == -1) { |
| perror("nftw"); |
| cleanup_function(); |
| fail_exit(); |
| } |
| |
| if (ret == 999) { |
| cleanup_function(); |
| fail_exit(); |
| } |
| } |
| |
| |
| /* |
| * void test9A() - tests the assertion: |
| * A call to int nftw(const char *path, int (*fn)(const char *, const |
| * struct stat *, int, struct FTW *), int depth, int flags) shall pass |
| * FTW_F as the third argument of the function fn when the object is a |
| * file |
| */ |
| |
| void |
| test9A(void) |
| { |
| int ret; |
| |
| #ifdef DEBUG |
| fprintf(temp, "TEST: nftw passes FTW_F as third arg to fn() for files\n"); |
| #endif |
| |
| if((ret = nftw("./tmp/data/dirg", test_func9, MAX_FD, |
| FTW_PHYS)) == -1) { |
| perror("nftw"); |
| cleanup_function(); |
| fail_exit(); |
| } |
| |
| if (ret == 999) { |
| cleanup_function(); |
| fail_exit(); |
| } |
| } |
| |
| |
| /* |
| * void test10A() - tests the assertion: |
| * A call to int nftw(const char *path, int (*fn)(const char *, const |
| * struct stat *, int, struct FTW *), int depth, int flags) shall pass |
| * FTW_D as the third argument of the function fn when the object is a |
| * directory. |
| */ |
| |
| void |
| test10A(void) |
| { |
| int ret; |
| |
| #ifdef DEBUG |
| fprintf(temp, "TEST: nftw passes FTW_D as third arg to fn() when file is directory\n"); |
| #endif |
| |
| if ((ret = nftw("./tmp/data/dirg", test_func10, MAX_FD, |
| FTW_PHYS)) == -1) { |
| perror("nftw"); |
| cleanup_function(); |
| fail_exit(); |
| } |
| |
| if (ret == 999) { |
| cleanup_function(); |
| fail_exit(); |
| } |
| } |
| |
| |
| /* |
| * void test11A() - tests the assertion: |
| * A call to int nftw(const char *path, int (*fn)(const char *, const |
| * struct stat *, int, struct FTW *), int depth, int flags) shall pass |
| * FTW_DP as the third argument of the function fn when the object is a |
| * directory and subdirectories have been visited. |
| */ |
| |
| void |
| test11A(void) |
| { |
| int i, ret; |
| |
| for (i = 0; i < nbads; i++) |
| if (badlist[i].i == FTW_D) |
| badlist[i].i = FTW_DP; |
| |
| #ifdef DEBUG |
| fprintf(temp, "TEST: nftw passes FTW_DP when file is directory and subdirs already visited\n"); |
| #endif |
| |
| if((ret = nftw("./tmp/data/dirg", test_func11, MAX_FD, FTW_DEPTH | |
| FTW_PHYS)) == -1) { |
| perror("nftw"); |
| cleanup_function(); |
| fail_exit(); |
| } |
| |
| if (ret == 999) { |
| cleanup_function(); |
| fail_exit(); |
| } |
| } |
| |
| |
| /* |
| * void test12A() - tests the assertion: |
| * A call to int nftw(const char *path, int (*fn)(const char *, const |
| * struct stat *, int, struct FTW *), int depth, int flags) shall pass |
| * FTW_SL as the third argument of the function fn when the object is a |
| * symbolic link. |
| */ |
| |
| void |
| test12A(void) |
| { |
| int ret; |
| |
| #ifdef DEBUG |
| fprintf(temp, |
| "TEST: nftw wth FTW_PHYS passes FTW_SL when file is symlink\n"); |
| #endif |
| |
| if((ret = nftw("./tmp/data/dirg", test_func12, MAX_FD, |
| FTW_PHYS)) == -1) { |
| perror("nftw"); |
| cleanup_function(); |
| fail_exit(); |
| } |
| |
| if (ret == 999) { |
| cleanup_function(); |
| fail_exit(); |
| } |
| } |
| |
| |
| /* |
| * void test13A() - tests the assertion: |
| * A call to int nftw(const char *path, int (*fn)(const char *, const |
| * struct stat *, int, struct FTW *), int depth, int flags) shall pass |
| * FTW_SLN as the third argument of the function fn when the object is a |
| * symbolic link that does not name an existing file. |
| */ |
| |
| void |
| test13A(void) |
| { |
| int i, ret; |
| |
| if(unlink("./tmp/byebye") == -1){ |
| perror("unlink"); |
| cleanup_function(); |
| fail_exit(); |
| } |
| |
| for (i = 0; i < nbads; i++) |
| if (badlist[i].i == FTW_SL) |
| badlist[i].i = FTW_SLN; |
| |
| #ifdef DEBUG |
| fprintf(temp, "TEST: nftw with FTW_PHYS passes FTW_SLN when file"); |
| fprintf(temp, " is symlink pointing \n to non-existent file\n"); |
| #endif |
| |
| if((ret = nftw("./tmp/data/dirg", test_func13, MAX_FD, |
| FTW_PHYS)) == -1) { |
| perror("nftw"); |
| cleanup_function(); |
| fail_exit(); |
| } |
| |
| if (ret == 999) { |
| cleanup_function(); |
| fail_exit(); |
| } |
| } |
| |
| |
| /* |
| * void test14A() - tests the assertion: |
| * A call to int nftw(const char *path, int (*fn)(const char *, const |
| * struct stat *, int, struct FTW *), int depth, int flags) shall pass |
| * FTW_DNR as the third argument of the function fn when the object is a |
| * directory that cannot be read. |
| */ |
| |
| void |
| test14A(void) |
| { |
| int ret; |
| |
| #ifdef DEBUG |
| fprintf(temp, "TEST: nftw passes FTW_DNR when file is directory that cannot be read\n"); |
| #endif |
| |
| if((ret = nftw("./tmp/data/d333", test_func14, MAX_FD, 0)) == -1) { |
| perror("nftw"); |
| cleanup_function(); |
| fail_exit(); |
| } |
| |
| if (ret == 999) { |
| cleanup_function(); |
| fail_exit(); |
| } |
| } |
| |
| |
| /* |
| * void test15A() - tests the assertion: |
| * A call to int nftw(const char *path, int (*fn)(const char *, const |
| * struct stat *, int, struct FTW *), int depth, int flags) shall pass |
| * FTW_NS as the third argument of the function fn when stat() failed on |
| * the object because of lack of appropriate permission. |
| */ |
| |
| void |
| test15A(void) |
| { |
| int ret; |
| |
| #ifdef DEBUG |
| fprintf(temp, "TEST: nftw(path, fn, depth, FTW_PHYS) passes FTW_NS when dir unsearchable\n"); |
| #endif |
| |
| if((ret = nftw("./tmp/data/d666", test_func15, MAX_FD,FTW_PHYS)) == -1) { |
| perror("nftw"); |
| cleanup_function(); |
| fail_exit(); |
| } |
| |
| if (ret == 999) { |
| cleanup_function(); |
| fail_exit(); |
| } |
| } |
| |
| |
| /* |
| * void test16A() - tests the assertion: |
| * A call to int nftw(const char *path, int (*fn)(const char *, const |
| * struct stat *, int, struct FTW *), int depth, int flags) shall pass a |
| * structure which contains the offset into the pathname of the object |
| * and the depth relative to the root of the walk starting from 0 as the |
| * fourth argument of the function fn. |
| */ |
| |
| void |
| test16A(void) |
| { |
| char path[PATH_MAX + NAME_MAX]; |
| char orig[PATH_MAX]; |
| |
| if(getcwd(orig, sizeof(orig)) == NULL) { |
| perror("getcwd on original wd"); |
| cleanup_function(); |
| fail_exit(); |
| } |
| |
| strcpy(path, orig); |
| (void)strcat(path, "/tmp/data/dirg"); |
| |
| #ifdef DEBUG |
| fprintf(temp, "TEST: nftw with absolute pathname %s\n", path); |
| #endif |
| |
| if((s2 = nftw(path, test_func16, MAX_FD, 0)) == -1) { |
| perror("nftw"); |
| cleanup_function(); |
| fail_exit(); |
| } |
| if (s2 == 999) { |
| cleanup_function(); |
| fail_exit(); |
| } |
| |
| (void)strcpy(path, "./tmp/data/dirg"); |
| |
| #ifdef DEBUG |
| fprintf(temp, "TEST: nftw with relative pathname %s\n", path); |
| #endif |
| |
| if((s2 = nftw(path, test_func16, MAX_FD, 0)) == -1) { |
| perror("nftw"); |
| cleanup_function(); |
| fail_exit(); |
| } |
| |
| if (s2 == 999) { |
| cleanup_function(); |
| fail_exit(); |
| } |
| } |
| |
| |
| /* |
| * void test17A() - tests the assertion: |
| * A call to int nftw(const char *path, int (*fn)(const char *, const |
| * struct stat *, int, struct FTW *), int depth, int flags) shall pass |
| * FTW_SL as the third argument to the function fn if and only if the |
| * FTW_PHYS flag is included in flags. |
| */ |
| |
| void |
| test17A(void) |
| { |
| int ret; |
| |
| visit = 0; |
| |
| #ifdef DEBUG |
| fprintf(temp, "TEST: nftw with FTW_PHYS passes FTW_SL for symlink\n"); |
| #endif |
| |
| if((ret=nftw("./tmp/data/dirl", test_func17, MAX_FD, FTW_PHYS)) == -1) { |
| perror("nftw"); |
| cleanup_function(); |
| fail_exit(); |
| } |
| if (ret != 999) { |
| fprintf(temp, "ERROR: nftw() failed to find symbolic link\n"); |
| cleanup_function(); |
| fail_exit(); |
| } |
| |
| visit = 0; |
| |
| #ifdef DEBUG |
| fprintf(temp, "TEST: nftw without FTW_PHYS does not pass FTW_SL for symlink\n"); |
| #endif |
| |
| if((ret = nftw("./tmp/data/dirl", test_func17, MAX_FD, 0)) == -1) { |
| perror("nftw"); |
| cleanup_function(); |
| fail_exit(); |
| } |
| if (ret == 999) { |
| fprintf(temp, "ERROR: nftw() found symbolic link\n"); |
| cleanup_function(); |
| fail_exit(); |
| } |
| } |
| |
| |
| /* |
| * void test18A() - tests the assertion: |
| * A call to int nftw(const char *path, int (*fn)(const char *, const |
| * struct stat *, int, struct FTW *), int depth, int flags) shall pass |
| * FTW_SLN as the third argument to the function fn if and only if the |
| * FTW_PHYS flag is not included in flags. |
| */ |
| |
| void |
| test18A(void) |
| { |
| int ret; |
| |
| unlink("./tmp/byebye"); |
| |
| visit=0; |
| |
| #ifdef DEBUG |
| fprintf(temp, "TEST: nftw with FTW_PHYS does not pass FTW_SLN\n"); |
| #endif |
| |
| if((ret = nftw("./tmp/data/dirg", test_func18, MAX_FD, |
| FTW_PHYS)) == -1) { |
| perror("nftw"); |
| cleanup_function(); |
| fail_exit(); |
| } |
| if (ret == 999) { |
| fprintf(temp, "ERROR: nftw() passed FTW_SLN\n"); |
| cleanup_function(); |
| fail_exit(); |
| } |
| |
| visit=0; |
| |
| #ifdef DEBUG |
| fprintf(temp, "TEST: nftw without FTW_PHYS passes FTW_SLN\n"); |
| #endif |
| |
| if((ret=nftw("./tmp/data/dirg", test_func18, MAX_FD, 0)) == -1) { |
| perror("nftw"); |
| cleanup_function(); |
| fail_exit(); |
| } |
| |
| if (visit == 1) { |
| if (ret == 999) { |
| /* Test is passed */ |
| return; |
| } else { |
| fprintf(temp, "ERROR: nftw passed FTW_SLN but did"); |
| fprintf(temp, "not return value returned by fn()\n"); |
| cleanup_function(); |
| fail_exit(); |
| } |
| } else { |
| fprintf(temp, "ERROR: nftw() did not pass FTW_SLN\n"); |
| cleanup_function(); |
| fail_exit(); |
| } |
| } |
| |
| |
| /* |
| * void test19A() - tests the assertion: |
| * On a call to int nftw(const char *path, int (*fn)(const char *, const |
| * struct stat *, int, struct FTW *), int depth, int flags) when the |
| * third argument passed to the function fn is FTW_DNR then the |
| * descendants of the directory shall not be processed. |
| */ |
| |
| void |
| test19A(void) |
| { |
| int ret_val; |
| |
| #ifdef DEBUG |
| fprintf(temp, "TEST: Can not traverse directory with no read permission\n"); |
| #endif |
| |
| visit = 0; |
| |
| ret_val = nftw("./tmp/data/d333", test_func19, MAX_FD, 0); |
| if (ret_val == -1) { |
| perror("nftw"); |
| cleanup_function(); |
| fail_exit(); |
| } |
| |
| if (ret_val == 999) { |
| cleanup_function(); |
| fail_exit(); |
| } |
| |
| #ifdef DEBUG |
| fprintf(temp, "TEST: fn only be called once\n"); |
| #endif |
| |
| if (visit != 1) |
| { |
| fprintf(temp, "ERROR: %s","Directory without read permission allows traversing\n"); |
| fprintf(temp, " Visited %d files\n", visit); |
| cleanup_function(); |
| fail_exit(); |
| } |
| } |
| |
| |
| /* |
| * void test20A() - tests the assertion: |
| * A call to int nftw(const char *path, int (*fn)(const char *, const |
| * struct stat *, int, struct FTW *), int depth, int flags) shall close |
| * any file descriptors or directory streams used to traverse the |
| * directory tree. |
| */ |
| |
| void |
| test20A(void) |
| { |
| int fd, nfd; |
| |
| #ifdef DEBUG |
| fprintf(temp, "TEST: File descriptors used in traversal are closed\n"); |
| #endif |
| |
| if((fd=open("./tmp/data/dirh", O_RDONLY)) == -1) { |
| perror("close"); |
| cleanup_function(); |
| fail_exit(); |
| } |
| |
| if(close(fd) == -1) { |
| perror("close"); |
| cleanup_function(); |
| fail_exit(); |
| } |
| |
| if(nftw("./tmp/data/dirh", test_func20, 1, 0) == -1) { |
| perror("nftw"); |
| cleanup_function(); |
| fail_exit(); |
| } |
| |
| if((nfd=open("./tmp/data/dirh", O_RDONLY)) == -1) { |
| perror("open"); |
| cleanup_function(); |
| fail_exit(); |
| } |
| |
| if (nfd != fd) { |
| fprintf(temp, "ERROR: %s,fd == %d ofd = %d", "nftw did not close all file descriptors used in traversal\n", nfd, fd); |
| cleanup_function(); |
| fail_exit(); |
| } |
| |
| if(close(nfd) == -1) { |
| perror("close"); |
| cleanup_function(); |
| fail_exit(); |
| } |
| } |
| |
| |
| /* |
| * void test21A() - tests the assertion: |
| * On a call to int nftw(const char *path, int (*fn)(const char *, const |
| * struct stat *, int, struct FTW *), int depth, int flags) shall |
| * be the maximum number of file descriptors used for the search. |
| */ |
| |
| void |
| test21A(void) |
| { |
| char path[] = "./tmp/data/dirh"; |
| int ret_val; |
| |
| #ifdef DEBUG |
| fprintf(temp, "TEST: No more than depth file descriptors used in traversal\n"); |
| #endif |
| |
| /*this is the fd we expect if 0 are used*/ |
| if((next_fd[0] = open(path, O_RDONLY)) == -1) { |
| perror("open next_fd[0]"); |
| cleanup_function(); |
| fail_exit(); |
| } |
| |
| /*this is the fd we expect if 1 is used*/ |
| if((next_fd[1] = open(path, O_RDONLY)) == -1) { |
| perror("open next_fd[1]"); |
| cleanup_function(); |
| fail_exit(); |
| } |
| |
| if(close(next_fd[0]) == -1) { |
| perror("close next_fd[0]"); |
| cleanup_function(); |
| fail_exit(); |
| } |
| |
| if(close(next_fd[1]) == -1) { |
| perror("close next_fd[1]"); |
| cleanup_function(); |
| fail_exit(); |
| } |
| |
| visit=0; |
| ret_val=nftw(path, test_func21, 1, 0); |
| if (ret_val == -1) { |
| perror("nftw"); |
| cleanup_function(); |
| fail_exit(); |
| } |
| |
| if (ret_val == 999) { |
| cleanup_function(); |
| fail_exit(); |
| } |
| } |
| |
| |
| /* |
| * void test22A() - tests the assertion: |
| * A call to int nftw(const char *path, int (*fn)(const char *, const |
| * struct stat *, int, struct FTW *), int depth, int flags) shall use at |
| * most one file descriptor for each directory level. |
| */ |
| |
| void |
| test22A(void) |
| { |
| char path[] = "./tmp/data/dirh"; |
| int ret_val, i; |
| |
| for (i = 0; i < 4; i++) { |
| if((next_fd[i] = open(path, O_RDONLY)) == -1) { |
| perror("open"); |
| cleanup_function(); |
| fail_exit(); |
| } |
| } |
| |
| for (i = 0; i < 4; i++) { |
| if(close(next_fd[i]) == -1) { |
| perror("close"); |
| cleanup_function(); |
| fail_exit(); |
| } |
| } |
| |
| visit = 0; |
| |
| #ifdef DEBUG |
| fprintf(temp, "TEST: No more than 1 fd per level is used in traversal\n"); |
| #endif |
| |
| ret_val = nftw(path, test_func22, MAX_FD, 0); |
| |
| if (ret_val == -1) { |
| perror("nftw"); |
| cleanup_function(); |
| fail_exit(); |
| } |
| |
| if (ret_val == 999) { |
| cleanup_function(); |
| fail_exit(); |
| } |
| } |
| |
| |
| /* |
| * void test23A() - tests the assertion: |
| * A call to int nftw(const char *path, int (*fn)(const char *, const |
| * struct stat *, int, struct FTW *), int depth, int flags) when the |
| * function fn returns a non-zero value shall stop and return the value |
| * returned by fn. |
| */ |
| |
| void |
| test23A(void) |
| { |
| int ret; |
| |
| visit=0; |
| |
| #ifdef DEBUG |
| fprintf(temp, "TEST: The function nftw should return with value set by fn\n"); |
| #endif |
| |
| if((ret=nftw("./tmp/data/dirh", test_func23, MAX_FD, FTW_PHYS)) == -1) { |
| perror("nftw"); |
| cleanup_function(); |
| fail_exit(); |
| } |
| |
| if (ret != 999) { |
| fprintf(temp, "ERROR: nftw did not return value returned by fn()\n"); |
| cleanup_function(); |
| fail_exit(); |
| } |
| if(visit != 4){ |
| fprintf(temp, "ERROR: nftw() did not return immediately on non-zero fn() return\n"); |
| cleanup_function(); |
| fail_exit(); |
| } |
| } |
| |
| |
| /* |
| * void test24A() - tests the assertion: |
| * ENAMETOOLONG in errno and return -1 on a call to int nftw(const char |
| * *path, int (*fn)(const char *, const struct stat *, int, struct FTW |
| * *), int depth, int flags) when the length of path exceeds PATH_MAX. |
| */ |
| |
| void |
| test24A(void) |
| { |
| test_ENAMETOOLONG_path("nftw", callback, -1); |
| } |
| |
| |
| /* |
| * void test25A() - tests the assertion: |
| * ENAMETOOLONG in errno and return -1 on a call to int nftw(const char |
| * *path, int (*fn)(const char *, const struct stat *, int, struct FTW |
| * *), int depth, int flags) when a component of path exceeds NAME_MAX. |
| */ |
| |
| void |
| test25A(void) |
| { |
| test_ENAMETOOLONG_name("nftw", callback, -1); |
| } |
| |
| |
| /* |
| * void test26A() - tests the assertion: |
| * ENOENT in errno and return -1 on a call to int nftw(const char *path, |
| * int (*fn)(const char *, const struct stat *, int, struct FTW *), int |
| * depth, int flags) when path points to a file which does not exist. |
| */ |
| |
| void |
| test26A(void) |
| { |
| #ifdef DEBUG |
| fprintf(temp, "TEST: [ENOENT] && -1 returned by nftw\n"); |
| #endif |
| |
| test_ENOENT_nofile("nftw", callback, -1); |
| } |
| |
| |
| /* |
| * void test27A() - tests the assertion: |
| * ENOENT in errno and return -1 on a call to int nftw(const char *path, |
| * int (*fn)(const char *, const struct stat *, int, struct FTW *), int |
| * depth, int flags) when path points to an empty string. |
| */ |
| |
| void |
| test27A(void) |
| { |
| #ifdef DEBUG |
| fprintf(temp, "TEST: The function nftw should return with a -1\n"); |
| #endif |
| |
| test_ENOENT_empty("nftw", callback, -1); |
| } |
| |
| |
| /* |
| * void test28A() - tests the assertion: |
| * ENOTDIR in errno and return -1 on a call to int nftw(const char |
| * *path, int (*fn)(const char *, const struct stat *, int, struct FTW |
| * *), int depth, int flags) when path is not a directory. |
| */ |
| |
| void |
| test28A(void) |
| { |
| #ifdef DEBUG |
| fprintf(temp, "TEST: [ENOTDIR] && -1 returned by nftw\n"); |
| #endif |
| |
| test_ENOTDIR("nftw", callback, -1); |
| } |
| |
| |
| /* |
| * void test29A() - tests the assertion: |
| * EACCES in errno and return -1 on a call to int nftw(const char *path, |
| * int (*fn)(const char *, const struct stat *, int, struct FTW *), int |
| * depth, int flags) when search permission is denied for any component |
| * of path. |
| */ |
| |
| void |
| test29A(void) |
| { |
| if(chmod("./tmp/data/d333", (mode_t)S_IRUSR) == -1){ |
| perror("chmod"); |
| cleanup_function(); |
| fail_exit(); |
| } |
| |
| #ifdef DEBUG |
| fprintf(temp, "TEST: [EACCES] && -1 returned by nftw\n"); |
| #endif |
| |
| test_ENOTDIR("nftw", callback, -1); |
| } |
| |
| |
| /* |
| * void test30A() - tests the assertion: |
| * EACCES in errno and return -1 on a call to int nftw(const char *path, |
| * int (*fn)(const char *, const struct stat *, int, struct FTW *), int |
| * depth, int flags) when read permission is denied for path. |
| */ |
| |
| void |
| test30A(void) |
| { |
| if(chmod("./tmp/data/d333", (mode_t)S_IXUSR) == -1){ |
| perror("chmod"); |
| cleanup_function(); |
| fail_exit(); |
| } |
| |
| #ifdef DEBUG |
| fprintf(temp, "TEST: [EACCES] && -1 returned by nftw\n"); |
| #endif |
| test_ENOTDIR("nftw", callback, -1); |
| } |
| |
| |