| /* |
| * Copyright © 2019 Google, LLC |
| * |
| * Permission is hereby granted, free of charge, to any person obtaining a |
| * copy of this software and associated documentation files (the "Software"), |
| * to deal in the Software without restriction, including without limitation |
| * the rights to use, copy, modify, merge, publish, distribute, sublicense, |
| * and/or sell copies of the Software, and to permit persons to whom the |
| * Software is furnished to do so, subject to the following conditions: |
| * |
| * The above copyright notice and this permission notice (including the next |
| * paragraph) shall be included in all copies or substantial portions of the |
| * Software. |
| * |
| * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
| * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
| * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
| * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
| * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
| * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS |
| * IN THE SOFTWARE. |
| */ |
| |
| #include "util/os_dirent.h" |
| #include <gtest/gtest.h> |
| |
| constexpr int kFileCount = 1000; |
| |
| #ifdef __Fuchsia__ |
| #include "os/fuchsia.h" |
| |
| #include <fuchsia/io/llcpp/fidl.h> |
| #include <lib/fdio/directory.h> |
| #include <lib/zx/channel.h> |
| |
| static int fuchsia_open_callback(const char* name, zx_handle_t handle) |
| { |
| return fdio_service_connect(name, handle); |
| } |
| |
| struct String { |
| ~String() { Reset(); } |
| |
| void Alloc(int size) { ptr = new char[size]; } |
| |
| void Reset() |
| { |
| delete[] ptr; |
| ptr = nullptr; |
| } |
| |
| char* ptr = nullptr; |
| }; |
| |
| static bool fuchsia_create_files(String files[kFileCount]) |
| { |
| for (uint32_t i = 0; i < kFileCount; i++) { |
| zx::channel channel0, channel1; |
| zx_status_t status = zx::channel::create(0, &channel0, &channel1); |
| |
| status = |
| fdio_open(files[i].ptr, |
| ::fuchsia_io::wire::kOpenFlagCreate | ::fuchsia_io::wire::kOpenRightWritable, |
| channel0.release()); |
| if (status != ZX_OK) { |
| printf("fdio_open(%s) failed: %d\n", files[i].ptr, status); |
| return false; |
| } |
| } |
| return true; |
| } |
| #endif |
| |
| TEST(os_dirent, readdir) |
| { |
| const char* path = "/tmp"; |
| const int path_len = strlen(path); |
| |
| String files[kFileCount]; |
| for (uint32_t i = 0; i < kFileCount; i++) { |
| files[i].Alloc(path_len + 16); |
| sprintf(files[i].ptr, "%s/%u", path, i); |
| } |
| |
| #ifdef __Fuchsia__ |
| EXPECT_TRUE(fuchsia_create_files(files)); |
| fuchsia_init(fuchsia_open_callback); |
| #endif |
| |
| os_dir_t* dir = os_opendir(path); |
| |
| while (struct os_dirent* entry = os_readdir(dir)) { |
| EXPECT_NE(0, entry->d_ino); |
| |
| String found_path; |
| found_path.Alloc(path_len + strlen(entry->d_name) + 16); |
| sprintf(found_path.ptr, "%s/%s", path, entry->d_name); |
| |
| for (uint32_t i = 0; i < kFileCount; i++) { |
| if (files[i].ptr && strcmp(files[i].ptr, found_path.ptr) == 0) { |
| files[i].Reset(); |
| break; |
| } |
| } |
| } |
| |
| for (uint32_t i = 0; i < kFileCount; i++) { |
| EXPECT_EQ(nullptr, files[i].ptr) << "Didn't find: " << files[i].ptr; |
| } |
| |
| os_closedir(dir); |
| |
| #ifdef __Fuchsia__ |
| // Don't bother removing tmp files |
| #endif |
| } |