1 /* 2 * Copyright (C) 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include <ftw.h> 18 19 #include <stdio.h> 20 #include <stdlib.h> 21 #include <sys/stat.h> 22 #include <sys/types.h> 23 #include <unistd.h> 24 25 #include "TemporaryFile.h" 26 27 #include <gtest/gtest.h> 28 29 static void MakeTree(const char* root) { 30 char path[PATH_MAX]; 31 32 snprintf(path, sizeof(path), "%s/dir", root); 33 ASSERT_EQ(0, mkdir(path, 0755)) << path; 34 snprintf(path, sizeof(path), "%s/dir/sub", root); 35 ASSERT_EQ(0, mkdir(path, 0555)) << path; 36 snprintf(path, sizeof(path), "%s/unreadable-dir", root); 37 ASSERT_EQ(0, mkdir(path, 0000)) << path; 38 39 snprintf(path, sizeof(path), "%s/dangler", root); 40 ASSERT_EQ(0, symlink("/does-not-exist", path)); 41 snprintf(path, sizeof(path), "%s/symlink", root); 42 ASSERT_EQ(0, symlink("sub2", path)); 43 44 int fd; 45 snprintf(path, sizeof(path), "%s/regular", root); 46 ASSERT_NE(-1, fd = open(path, O_CREAT|O_TRUNC, 0666)); 47 ASSERT_EQ(0, close(fd)); 48 } 49 50 void sanity_check_ftw(const char* fpath, const struct stat* sb, int tflag) { 51 ASSERT_TRUE(fpath != NULL); 52 ASSERT_TRUE(sb != NULL); 53 54 if (S_ISDIR(sb->st_mode)) { 55 EXPECT_TRUE(tflag == FTW_D || tflag == FTW_DNR || tflag == FTW_DP) << fpath; 56 } else if (S_ISLNK(sb->st_mode)) { 57 EXPECT_EQ(FTW_SL, tflag) << fpath; 58 } else { 59 EXPECT_EQ(FTW_F, tflag) << fpath; 60 } 61 } 62 63 void sanity_check_nftw(const char* fpath, const struct stat* sb, int tflag, struct FTW* ftwbuf) { 64 sanity_check_ftw(fpath, sb, tflag); 65 ASSERT_EQ('/', fpath[ftwbuf->base - 1]) << fpath; 66 } 67 68 int check_ftw(const char* fpath, const struct stat* sb, int tflag) { 69 sanity_check_ftw(fpath, sb, tflag); 70 return 0; 71 } 72 73 int check_ftw64(const char* fpath, const struct stat64* sb, int tflag) { 74 sanity_check_ftw(fpath, reinterpret_cast<const struct stat*>(sb), tflag); 75 return 0; 76 } 77 78 int check_nftw(const char* fpath, const struct stat* sb, int tflag, struct FTW* ftwbuf) { 79 sanity_check_nftw(fpath, sb, tflag, ftwbuf); 80 return 0; 81 } 82 83 int check_nftw64(const char* fpath, const struct stat64* sb, int tflag, struct FTW* ftwbuf) { 84 sanity_check_nftw(fpath, reinterpret_cast<const struct stat*>(sb), tflag, ftwbuf); 85 return 0; 86 } 87 88 TEST(ftw, ftw) { 89 TemporaryDir root; 90 MakeTree(root.dirname); 91 ASSERT_EQ(0, ftw(root.dirname, check_ftw, 128)); 92 } 93 94 TEST(ftw, ftw64) { 95 TemporaryDir root; 96 MakeTree(root.dirname); 97 ASSERT_EQ(0, ftw64(root.dirname, check_ftw64, 128)); 98 } 99 100 TEST(ftw, nftw) { 101 TemporaryDir root; 102 MakeTree(root.dirname); 103 ASSERT_EQ(0, nftw(root.dirname, check_nftw, 128, 0)); 104 } 105 106 TEST(ftw, nftw64) { 107 TemporaryDir root; 108 MakeTree(root.dirname); 109 ASSERT_EQ(0, nftw64(root.dirname, check_nftw64, 128, 0)); 110 } 111