1063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes/* 2063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes * Copyright (C) 2012 The Android Open Source Project 3063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes * 4063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes * Licensed under the Apache License, Version 2.0 (the "License"); 5063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes * you may not use this file except in compliance with the License. 6063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes * You may obtain a copy of the License at 7063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes * 8063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes * http://www.apache.org/licenses/LICENSE-2.0 9063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes * 10063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes * Unless required by applicable law or agreed to in writing, software 11063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes * distributed under the License is distributed on an "AS IS" BASIS, 12063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes * See the License for the specific language governing permissions and 14063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes * limitations under the License. 15063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes */ 16063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes 17063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes#include <gtest/gtest.h> 18063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes 19063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes#include <dirent.h> 20063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes#include <errno.h> 21063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes#include <fcntl.h> 22063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes#include <limits.h> 23063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes#include <sys/stat.h> 24063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes#include <sys/types.h> 25063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes#include <unistd.h> 26063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes 27063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes#include <algorithm> 28063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes#include <set> 29063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes#include <string> 30063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes 31063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughesstatic void CheckProcSelf(std::set<std::string>& names) { 32063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes // We have a good idea of what should be in /proc/self. 33063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes ASSERT_TRUE(names.find(".") != names.end()); 34063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes ASSERT_TRUE(names.find("..") != names.end()); 35063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes ASSERT_TRUE(names.find("cmdline") != names.end()); 36063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes ASSERT_TRUE(names.find("fd") != names.end()); 37063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes ASSERT_TRUE(names.find("stat") != names.end()); 38063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes} 39063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes 40db1ea3474899ebbd783aba872d3005f95a816d0fElliott Hughestemplate <typename DirEntT> 41db1ea3474899ebbd783aba872d3005f95a816d0fElliott Hughesvoid ScanEntries(DirEntT** entries, int entry_count, 42db1ea3474899ebbd783aba872d3005f95a816d0fElliott Hughes std::set<std::string>& name_set, std::vector<std::string>& name_list) { 43db1ea3474899ebbd783aba872d3005f95a816d0fElliott Hughes for (size_t i = 0; i < static_cast<size_t>(entry_count); ++i) { 44db1ea3474899ebbd783aba872d3005f95a816d0fElliott Hughes name_set.insert(entries[i]->d_name); 45db1ea3474899ebbd783aba872d3005f95a816d0fElliott Hughes name_list.push_back(entries[i]->d_name); 46db1ea3474899ebbd783aba872d3005f95a816d0fElliott Hughes free(entries[i]); 47db1ea3474899ebbd783aba872d3005f95a816d0fElliott Hughes } 48db1ea3474899ebbd783aba872d3005f95a816d0fElliott Hughes free(entries); 49db1ea3474899ebbd783aba872d3005f95a816d0fElliott Hughes} 50db1ea3474899ebbd783aba872d3005f95a816d0fElliott Hughes 51db1ea3474899ebbd783aba872d3005f95a816d0fElliott HughesTEST(dirent, scandir_scandir64) { 52063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes // Get everything from /proc/self... 53063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes dirent** entries; 54063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes int entry_count = scandir("/proc/self", &entries, NULL, alphasort); 55063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes ASSERT_GE(entry_count, 0); 56063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes 57db1ea3474899ebbd783aba872d3005f95a816d0fElliott Hughes dirent64** entries64; 58db1ea3474899ebbd783aba872d3005f95a816d0fElliott Hughes int entry_count64 = scandir64("/proc/self", &entries64, NULL, alphasort64); 59db1ea3474899ebbd783aba872d3005f95a816d0fElliott Hughes ASSERT_EQ(entry_count, entry_count64); 60db1ea3474899ebbd783aba872d3005f95a816d0fElliott Hughes 61063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes // Turn the directory entries into a set and vector of the names. 62063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes std::set<std::string> name_set; 63063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes std::vector<std::string> unsorted_name_list; 64db1ea3474899ebbd783aba872d3005f95a816d0fElliott Hughes ScanEntries(entries, entry_count, name_set, unsorted_name_list); 65063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes 66063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes // No duplicates. 67063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes ASSERT_EQ(name_set.size(), unsorted_name_list.size()); 68063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes 69063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes // All entries sorted. 70063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes std::vector<std::string> sorted_name_list(unsorted_name_list); 71063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes std::sort(sorted_name_list.begin(), sorted_name_list.end()); 72063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes ASSERT_EQ(sorted_name_list, unsorted_name_list); 73063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes 74db1ea3474899ebbd783aba872d3005f95a816d0fElliott Hughes // scandir64 returned the same results as scandir. 75db1ea3474899ebbd783aba872d3005f95a816d0fElliott Hughes std::set<std::string> name_set64; 76db1ea3474899ebbd783aba872d3005f95a816d0fElliott Hughes std::vector<std::string> unsorted_name_list64; 77db1ea3474899ebbd783aba872d3005f95a816d0fElliott Hughes ScanEntries(entries64, entry_count64, name_set64, unsorted_name_list64); 78db1ea3474899ebbd783aba872d3005f95a816d0fElliott Hughes ASSERT_EQ(name_set, name_set64); 79db1ea3474899ebbd783aba872d3005f95a816d0fElliott Hughes ASSERT_EQ(unsorted_name_list, unsorted_name_list64); 80db1ea3474899ebbd783aba872d3005f95a816d0fElliott Hughes 81063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes CheckProcSelf(name_set); 82063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes} 83063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes 846331e806de41d98083f1bfa3661addfae4682c37Elliott HughesTEST(dirent, scandirat_scandirat64) { 856331e806de41d98083f1bfa3661addfae4682c37Elliott Hughes // Get everything from /proc/self... 866331e806de41d98083f1bfa3661addfae4682c37Elliott Hughes dirent** entries; 876331e806de41d98083f1bfa3661addfae4682c37Elliott Hughes int entry_count = scandir("/proc/self", &entries, NULL, alphasort); 886331e806de41d98083f1bfa3661addfae4682c37Elliott Hughes ASSERT_GE(entry_count, 0); 896331e806de41d98083f1bfa3661addfae4682c37Elliott Hughes 906331e806de41d98083f1bfa3661addfae4682c37Elliott Hughes int proc_fd = open("/proc", O_DIRECTORY); 916331e806de41d98083f1bfa3661addfae4682c37Elliott Hughes ASSERT_NE(-1, proc_fd); 926331e806de41d98083f1bfa3661addfae4682c37Elliott Hughes 936331e806de41d98083f1bfa3661addfae4682c37Elliott Hughes dirent** entries_at; 946331e806de41d98083f1bfa3661addfae4682c37Elliott Hughes int entry_count_at = scandirat(proc_fd, "self", &entries_at, NULL, alphasort); 956331e806de41d98083f1bfa3661addfae4682c37Elliott Hughes ASSERT_EQ(entry_count, entry_count_at); 966331e806de41d98083f1bfa3661addfae4682c37Elliott Hughes 976331e806de41d98083f1bfa3661addfae4682c37Elliott Hughes dirent64** entries_at64; 986331e806de41d98083f1bfa3661addfae4682c37Elliott Hughes int entry_count_at64 = scandirat64(proc_fd, "self", &entries_at64, NULL, alphasort64); 996331e806de41d98083f1bfa3661addfae4682c37Elliott Hughes ASSERT_EQ(entry_count, entry_count_at64); 1006331e806de41d98083f1bfa3661addfae4682c37Elliott Hughes 1016331e806de41d98083f1bfa3661addfae4682c37Elliott Hughes close(proc_fd); 1026331e806de41d98083f1bfa3661addfae4682c37Elliott Hughes 1036331e806de41d98083f1bfa3661addfae4682c37Elliott Hughes // scandirat and scandirat64 should return the same results as scandir. 1046331e806de41d98083f1bfa3661addfae4682c37Elliott Hughes std::set<std::string> name_set, name_set_at, name_set_at64; 1056331e806de41d98083f1bfa3661addfae4682c37Elliott Hughes std::vector<std::string> unsorted_name_list, unsorted_name_list_at, unsorted_name_list_at64; 1066331e806de41d98083f1bfa3661addfae4682c37Elliott Hughes ScanEntries(entries, entry_count, name_set, unsorted_name_list); 1076331e806de41d98083f1bfa3661addfae4682c37Elliott Hughes ScanEntries(entries_at, entry_count_at, name_set_at, unsorted_name_list_at); 1086331e806de41d98083f1bfa3661addfae4682c37Elliott Hughes ScanEntries(entries_at64, entry_count_at64, name_set_at64, unsorted_name_list_at64); 1096331e806de41d98083f1bfa3661addfae4682c37Elliott Hughes 1106331e806de41d98083f1bfa3661addfae4682c37Elliott Hughes ASSERT_EQ(name_set, name_set_at); 1116331e806de41d98083f1bfa3661addfae4682c37Elliott Hughes ASSERT_EQ(name_set, name_set_at64); 1126331e806de41d98083f1bfa3661addfae4682c37Elliott Hughes ASSERT_EQ(unsorted_name_list, unsorted_name_list_at); 1136331e806de41d98083f1bfa3661addfae4682c37Elliott Hughes ASSERT_EQ(unsorted_name_list, unsorted_name_list_at64); 1146331e806de41d98083f1bfa3661addfae4682c37Elliott Hughes} 1156331e806de41d98083f1bfa3661addfae4682c37Elliott Hughes 1166331e806de41d98083f1bfa3661addfae4682c37Elliott HughesTEST(dirent, scandir_ENOENT) { 1176331e806de41d98083f1bfa3661addfae4682c37Elliott Hughes dirent** entries; 1186331e806de41d98083f1bfa3661addfae4682c37Elliott Hughes errno = 0; 1196331e806de41d98083f1bfa3661addfae4682c37Elliott Hughes ASSERT_EQ(-1, scandir("/does-not-exist", &entries, nullptr, nullptr)); 1206331e806de41d98083f1bfa3661addfae4682c37Elliott Hughes ASSERT_EQ(ENOENT, errno); 1216331e806de41d98083f1bfa3661addfae4682c37Elliott Hughes} 1226331e806de41d98083f1bfa3661addfae4682c37Elliott Hughes 1236331e806de41d98083f1bfa3661addfae4682c37Elliott HughesTEST(dirent, scandir64_ENOENT) { 1246331e806de41d98083f1bfa3661addfae4682c37Elliott Hughes dirent64** entries; 1256331e806de41d98083f1bfa3661addfae4682c37Elliott Hughes errno = 0; 1266331e806de41d98083f1bfa3661addfae4682c37Elliott Hughes ASSERT_EQ(-1, scandir64("/does-not-exist", &entries, nullptr, nullptr)); 1276331e806de41d98083f1bfa3661addfae4682c37Elliott Hughes ASSERT_EQ(ENOENT, errno); 1286331e806de41d98083f1bfa3661addfae4682c37Elliott Hughes} 1296331e806de41d98083f1bfa3661addfae4682c37Elliott Hughes 1306331e806de41d98083f1bfa3661addfae4682c37Elliott HughesTEST(dirent, scandirat_ENOENT) { 1316331e806de41d98083f1bfa3661addfae4682c37Elliott Hughes int root_fd = open("/", O_DIRECTORY | O_RDONLY); 1326331e806de41d98083f1bfa3661addfae4682c37Elliott Hughes ASSERT_NE(-1, root_fd); 1336331e806de41d98083f1bfa3661addfae4682c37Elliott Hughes dirent** entries; 1346331e806de41d98083f1bfa3661addfae4682c37Elliott Hughes errno = 0; 1356331e806de41d98083f1bfa3661addfae4682c37Elliott Hughes ASSERT_EQ(-1, scandirat(root_fd, "does-not-exist", &entries, nullptr, nullptr)); 1366331e806de41d98083f1bfa3661addfae4682c37Elliott Hughes ASSERT_EQ(ENOENT, errno); 1376331e806de41d98083f1bfa3661addfae4682c37Elliott Hughes close(root_fd); 1386331e806de41d98083f1bfa3661addfae4682c37Elliott Hughes} 1396331e806de41d98083f1bfa3661addfae4682c37Elliott Hughes 1406331e806de41d98083f1bfa3661addfae4682c37Elliott HughesTEST(dirent, scandirat64_ENOENT) { 1416331e806de41d98083f1bfa3661addfae4682c37Elliott Hughes int root_fd = open("/", O_DIRECTORY | O_RDONLY); 1426331e806de41d98083f1bfa3661addfae4682c37Elliott Hughes ASSERT_NE(-1, root_fd); 1436331e806de41d98083f1bfa3661addfae4682c37Elliott Hughes dirent64** entries; 1446331e806de41d98083f1bfa3661addfae4682c37Elliott Hughes errno = 0; 1456331e806de41d98083f1bfa3661addfae4682c37Elliott Hughes ASSERT_EQ(-1, scandirat64(root_fd, "does-not-exist", &entries, nullptr, nullptr)); 1466331e806de41d98083f1bfa3661addfae4682c37Elliott Hughes ASSERT_EQ(ENOENT, errno); 1476331e806de41d98083f1bfa3661addfae4682c37Elliott Hughes close(root_fd); 1486331e806de41d98083f1bfa3661addfae4682c37Elliott Hughes} 1496331e806de41d98083f1bfa3661addfae4682c37Elliott Hughes 150063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott HughesTEST(dirent, fdopendir_invalid) { 151063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes ASSERT_TRUE(fdopendir(-1) == NULL); 1525e3fc43ddeada547a155c6f561a12ff0b16e02d3Elliott Hughes ASSERT_EQ(EBADF, errno); 153063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes 154063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes int fd = open("/dev/null", O_RDONLY); 155063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes ASSERT_NE(fd, -1); 156063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes ASSERT_TRUE(fdopendir(fd) == NULL); 1575e3fc43ddeada547a155c6f561a12ff0b16e02d3Elliott Hughes ASSERT_EQ(ENOTDIR, errno); 158063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes close(fd); 159063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes} 160063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes 161063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott HughesTEST(dirent, fdopendir) { 162063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes int fd = open("/proc/self", O_RDONLY); 163063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes DIR* d = fdopendir(fd); 164063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes ASSERT_TRUE(d != NULL); 165063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes dirent* e = readdir(d); 166063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes ASSERT_STREQ(e->d_name, "."); 167063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes ASSERT_EQ(closedir(d), 0); 168063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes 169063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes // fdopendir(3) took ownership, so closedir(3) closed our fd. 170063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes ASSERT_EQ(close(fd), -1); 1715e3fc43ddeada547a155c6f561a12ff0b16e02d3Elliott Hughes ASSERT_EQ(EBADF, errno); 172063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes} 173063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes 174063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott HughesTEST(dirent, opendir_invalid) { 175063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes ASSERT_TRUE(opendir("/does/not/exist") == NULL); 1765e3fc43ddeada547a155c6f561a12ff0b16e02d3Elliott Hughes ASSERT_EQ(ENOENT, errno); 177063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes 178063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes ASSERT_TRUE(opendir("/dev/null") == NULL); 1795e3fc43ddeada547a155c6f561a12ff0b16e02d3Elliott Hughes ASSERT_EQ(ENOTDIR, errno); 180063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes} 181063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes 182063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott HughesTEST(dirent, opendir) { 183063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes DIR* d = opendir("/proc/self"); 184063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes ASSERT_TRUE(d != NULL); 185063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes dirent* e = readdir(d); 186063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes ASSERT_STREQ(e->d_name, "."); 187063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes ASSERT_EQ(closedir(d), 0); 188063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes} 189063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes 190063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott HughesTEST(dirent, closedir_invalid) { 191063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes DIR* d = NULL; 192063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes ASSERT_EQ(closedir(d), -1); 1935e3fc43ddeada547a155c6f561a12ff0b16e02d3Elliott Hughes ASSERT_EQ(EINVAL, errno); 194063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes} 195063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes 196063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott HughesTEST(dirent, closedir) { 197063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes DIR* d = opendir("/proc/self"); 198063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes ASSERT_TRUE(d != NULL); 199063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes ASSERT_EQ(closedir(d), 0); 200063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes} 201063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes 202063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott HughesTEST(dirent, readdir) { 203063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes DIR* d = opendir("/proc/self"); 204063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes ASSERT_TRUE(d != NULL); 205063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes std::set<std::string> name_set; 206063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes errno = 0; 207063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes dirent* e; 208063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes while ((e = readdir(d)) != NULL) { 209063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes name_set.insert(e->d_name); 210063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes } 211063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes // Reading to the end of the directory is not an error. 212063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes // readdir(3) returns NULL, but leaves errno as 0. 2135e3fc43ddeada547a155c6f561a12ff0b16e02d3Elliott Hughes ASSERT_EQ(0, errno); 214063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes ASSERT_EQ(closedir(d), 0); 215063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes 216063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes CheckProcSelf(name_set); 217063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes} 218063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes 219db1ea3474899ebbd783aba872d3005f95a816d0fElliott HughesTEST(dirent, readdir64) { 220db1ea3474899ebbd783aba872d3005f95a816d0fElliott Hughes DIR* d = opendir("/proc/self"); 221db1ea3474899ebbd783aba872d3005f95a816d0fElliott Hughes ASSERT_TRUE(d != NULL); 222db1ea3474899ebbd783aba872d3005f95a816d0fElliott Hughes std::set<std::string> name_set; 223db1ea3474899ebbd783aba872d3005f95a816d0fElliott Hughes errno = 0; 224db1ea3474899ebbd783aba872d3005f95a816d0fElliott Hughes dirent64* e; 225db1ea3474899ebbd783aba872d3005f95a816d0fElliott Hughes while ((e = readdir64(d)) != NULL) { 226db1ea3474899ebbd783aba872d3005f95a816d0fElliott Hughes name_set.insert(e->d_name); 227db1ea3474899ebbd783aba872d3005f95a816d0fElliott Hughes } 228db1ea3474899ebbd783aba872d3005f95a816d0fElliott Hughes // Reading to the end of the directory is not an error. 229db1ea3474899ebbd783aba872d3005f95a816d0fElliott Hughes // readdir64(3) returns NULL, but leaves errno as 0. 230db1ea3474899ebbd783aba872d3005f95a816d0fElliott Hughes ASSERT_EQ(0, errno); 231db1ea3474899ebbd783aba872d3005f95a816d0fElliott Hughes ASSERT_EQ(closedir(d), 0); 232db1ea3474899ebbd783aba872d3005f95a816d0fElliott Hughes 233db1ea3474899ebbd783aba872d3005f95a816d0fElliott Hughes CheckProcSelf(name_set); 234db1ea3474899ebbd783aba872d3005f95a816d0fElliott Hughes} 235db1ea3474899ebbd783aba872d3005f95a816d0fElliott Hughes 236063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott HughesTEST(dirent, readdir_r) { 237063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes DIR* d = opendir("/proc/self"); 238063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes ASSERT_TRUE(d != NULL); 239063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes std::set<std::string> name_set; 240063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes errno = 0; 241063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes dirent storage; 242063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes dirent* e = NULL; 243063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes while (readdir_r(d, &storage, &e) == 0 && e != NULL) { 244063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes name_set.insert(e->d_name); 245063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes } 246063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes // Reading to the end of the directory is not an error. 247063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes // readdir_r(3) returns NULL, but leaves errno as 0. 2485e3fc43ddeada547a155c6f561a12ff0b16e02d3Elliott Hughes ASSERT_EQ(0, errno); 249063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes ASSERT_EQ(closedir(d), 0); 250063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes 251063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes CheckProcSelf(name_set); 252063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes} 253063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes 254db1ea3474899ebbd783aba872d3005f95a816d0fElliott HughesTEST(dirent, readdir64_r) { 255db1ea3474899ebbd783aba872d3005f95a816d0fElliott Hughes DIR* d = opendir("/proc/self"); 256db1ea3474899ebbd783aba872d3005f95a816d0fElliott Hughes ASSERT_TRUE(d != NULL); 257db1ea3474899ebbd783aba872d3005f95a816d0fElliott Hughes std::set<std::string> name_set; 258db1ea3474899ebbd783aba872d3005f95a816d0fElliott Hughes errno = 0; 259db1ea3474899ebbd783aba872d3005f95a816d0fElliott Hughes dirent64 storage; 260db1ea3474899ebbd783aba872d3005f95a816d0fElliott Hughes dirent64* e = NULL; 261db1ea3474899ebbd783aba872d3005f95a816d0fElliott Hughes while (readdir64_r(d, &storage, &e) == 0 && e != NULL) { 262db1ea3474899ebbd783aba872d3005f95a816d0fElliott Hughes name_set.insert(e->d_name); 263db1ea3474899ebbd783aba872d3005f95a816d0fElliott Hughes } 264db1ea3474899ebbd783aba872d3005f95a816d0fElliott Hughes // Reading to the end of the directory is not an error. 265db1ea3474899ebbd783aba872d3005f95a816d0fElliott Hughes // readdir64_r(3) returns NULL, but leaves errno as 0. 266db1ea3474899ebbd783aba872d3005f95a816d0fElliott Hughes ASSERT_EQ(0, errno); 267db1ea3474899ebbd783aba872d3005f95a816d0fElliott Hughes ASSERT_EQ(closedir(d), 0); 268db1ea3474899ebbd783aba872d3005f95a816d0fElliott Hughes 269db1ea3474899ebbd783aba872d3005f95a816d0fElliott Hughes CheckProcSelf(name_set); 270db1ea3474899ebbd783aba872d3005f95a816d0fElliott Hughes} 271db1ea3474899ebbd783aba872d3005f95a816d0fElliott Hughes 272063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott HughesTEST(dirent, rewinddir) { 273063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes DIR* d = opendir("/proc/self"); 274063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes ASSERT_TRUE(d != NULL); 275063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes 276063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes // Get all the names once... 277063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes std::vector<std::string> pass1; 278063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes dirent* e; 279063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes while ((e = readdir(d)) != NULL) { 280063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes pass1.push_back(e->d_name); 281063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes } 282063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes 283063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes // ...rewind... 284063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes rewinddir(d); 285063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes 286063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes // ...and get all the names again. 287063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes std::vector<std::string> pass2; 288063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes while ((e = readdir(d)) != NULL) { 289063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes pass2.push_back(e->d_name); 290063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes } 291063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes 292063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes ASSERT_EQ(closedir(d), 0); 293063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes 294063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes // We should have seen the same names in the same order both times. 295063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes ASSERT_EQ(pass1.size(), pass2.size()); 296063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes for (size_t i = 0; i < pass1.size(); ++i) { 297063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes ASSERT_EQ(pass1[i], pass2[i]); 298063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes } 299063cfb2084ea4b12d3c85b2d2c44e888f0857eb4Elliott Hughes} 3005ca4a9e2da46db30ad6d8556b61679d138aaf88dYabin Cui 3015ca4a9e2da46db30ad6d8556b61679d138aaf88dYabin CuiTEST(dirent, seekdir_telldir) { 3025ca4a9e2da46db30ad6d8556b61679d138aaf88dYabin Cui DIR* d = opendir("/proc/self"); 3035ca4a9e2da46db30ad6d8556b61679d138aaf88dYabin Cui ASSERT_TRUE(d != NULL); 3045ca4a9e2da46db30ad6d8556b61679d138aaf88dYabin Cui std::vector<long> offset_list; 3055ca4a9e2da46db30ad6d8556b61679d138aaf88dYabin Cui std::vector<std::string> name_list; 3065ca4a9e2da46db30ad6d8556b61679d138aaf88dYabin Cui dirent* e = NULL; 3075ca4a9e2da46db30ad6d8556b61679d138aaf88dYabin Cui 3085ca4a9e2da46db30ad6d8556b61679d138aaf88dYabin Cui offset_list.push_back(telldir(d)); 3095ca4a9e2da46db30ad6d8556b61679d138aaf88dYabin Cui ASSERT_EQ(0L, offset_list.back()); 3105ca4a9e2da46db30ad6d8556b61679d138aaf88dYabin Cui 3115ca4a9e2da46db30ad6d8556b61679d138aaf88dYabin Cui while ((e = readdir(d)) != NULL) { 3125ca4a9e2da46db30ad6d8556b61679d138aaf88dYabin Cui name_list.push_back(e->d_name); 3135ca4a9e2da46db30ad6d8556b61679d138aaf88dYabin Cui offset_list.push_back(telldir(d)); 3145ca4a9e2da46db30ad6d8556b61679d138aaf88dYabin Cui // Make sure telldir() point to the next entry. 3155ca4a9e2da46db30ad6d8556b61679d138aaf88dYabin Cui ASSERT_EQ(e->d_off, offset_list.back()); 3165ca4a9e2da46db30ad6d8556b61679d138aaf88dYabin Cui } 3175ca4a9e2da46db30ad6d8556b61679d138aaf88dYabin Cui 3185ca4a9e2da46db30ad6d8556b61679d138aaf88dYabin Cui long end_offset = telldir(d); 3195ca4a9e2da46db30ad6d8556b61679d138aaf88dYabin Cui // telldir() should not pass the end of the file. 3205ca4a9e2da46db30ad6d8556b61679d138aaf88dYabin Cui ASSERT_EQ(offset_list.back(), end_offset); 3215ca4a9e2da46db30ad6d8556b61679d138aaf88dYabin Cui offset_list.pop_back(); 3225ca4a9e2da46db30ad6d8556b61679d138aaf88dYabin Cui 3235ca4a9e2da46db30ad6d8556b61679d138aaf88dYabin Cui for (size_t i = 0; i < offset_list.size(); ++i) { 3245ca4a9e2da46db30ad6d8556b61679d138aaf88dYabin Cui seekdir(d, offset_list[i]); 3255ca4a9e2da46db30ad6d8556b61679d138aaf88dYabin Cui ASSERT_EQ(offset_list[i], telldir(d)); 3265ca4a9e2da46db30ad6d8556b61679d138aaf88dYabin Cui e = readdir(d); 3275ca4a9e2da46db30ad6d8556b61679d138aaf88dYabin Cui ASSERT_TRUE(e != NULL); 3285ca4a9e2da46db30ad6d8556b61679d138aaf88dYabin Cui ASSERT_STREQ(name_list[i].c_str(), e->d_name); 3295ca4a9e2da46db30ad6d8556b61679d138aaf88dYabin Cui } 3305ca4a9e2da46db30ad6d8556b61679d138aaf88dYabin Cui for (int i = static_cast<int>(offset_list.size()) - 1; i >= 0; --i) { 3315ca4a9e2da46db30ad6d8556b61679d138aaf88dYabin Cui seekdir(d, offset_list[i]); 3325ca4a9e2da46db30ad6d8556b61679d138aaf88dYabin Cui ASSERT_EQ(offset_list[i], telldir(d)); 3335ca4a9e2da46db30ad6d8556b61679d138aaf88dYabin Cui e = readdir(d); 3345ca4a9e2da46db30ad6d8556b61679d138aaf88dYabin Cui ASSERT_TRUE(e != NULL); 3355ca4a9e2da46db30ad6d8556b61679d138aaf88dYabin Cui ASSERT_STREQ(name_list[i].c_str(), e->d_name); 3365ca4a9e2da46db30ad6d8556b61679d138aaf88dYabin Cui } 3375ca4a9e2da46db30ad6d8556b61679d138aaf88dYabin Cui 3385ca4a9e2da46db30ad6d8556b61679d138aaf88dYabin Cui // Seek to the end, read NULL. 3395ca4a9e2da46db30ad6d8556b61679d138aaf88dYabin Cui seekdir(d, end_offset); 3405ca4a9e2da46db30ad6d8556b61679d138aaf88dYabin Cui ASSERT_EQ(end_offset, telldir(d)); 3415ca4a9e2da46db30ad6d8556b61679d138aaf88dYabin Cui errno = 0; 3425ca4a9e2da46db30ad6d8556b61679d138aaf88dYabin Cui ASSERT_EQ(NULL, readdir(d)); 3435ca4a9e2da46db30ad6d8556b61679d138aaf88dYabin Cui ASSERT_EQ(0, errno); 3445ca4a9e2da46db30ad6d8556b61679d138aaf88dYabin Cui 3455ca4a9e2da46db30ad6d8556b61679d138aaf88dYabin Cui ASSERT_EQ(0, closedir(d)); 3465ca4a9e2da46db30ad6d8556b61679d138aaf88dYabin Cui} 347