brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.9 KiB · 9a3ef75 Raw
190 lines · cpp
1//===----------------------------------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9// REQUIRES: can-create-symlinks10// UNSUPPORTED: c++03, c++11, c++1411// UNSUPPORTED: no-filesystem12 13// Starting in Android N (API 24), SELinux policy prevents the shell user from14// creating a FIFO file.15// XFAIL: LIBCXX-ANDROID-FIXME && !android-device-api={{21|22|23}}16 17// <filesystem>18 19// file_status status(const path& p);20// file_status status(const path& p, error_code& ec) noexcept;21 22#include <filesystem>23 24#include "assert_macros.h"25#include "test_macros.h"26#include "filesystem_test_helper.h"27namespace fs = std::filesystem;28using namespace fs;29 30static void signature_test()31{32    const path p; ((void)p);33    std::error_code ec; ((void)ec);34    ASSERT_NOT_NOEXCEPT(status(p));35    ASSERT_NOEXCEPT(status(p, ec));36}37 38static void test_status_not_found()39{40    static_test_env static_env;41    const std::errc expect_errc = std::errc::no_such_file_or_directory;42    const path cases[] {43        static_env.DNE,44        static_env.BadSymlink45    };46    for (auto& p : cases) {47        std::error_code ec = std::make_error_code(std::errc::address_in_use);48        // test non-throwing overload.49        file_status st = status(p, ec);50        assert(ErrorIs(ec, expect_errc));51        assert(st.type() == file_type::not_found);52        assert(st.permissions() == perms::unknown);53        // test throwing overload. It should not throw even though it reports54        // that the file was not found.55        TEST_DOES_NOT_THROW(st = status(p));56        assert(st.type() == file_type::not_found);57        assert(st.permissions() == perms::unknown);58    }59}60 61// Windows doesn't support setting perms::none to trigger failures62// reading directories. Imaginary files under GetWindowsInaccessibleDir()63// produce no_such_file_or_directory, not the error codes this test checks64// for. Finally, status() for a too long file name doesn't return errors65// on windows.66#ifndef TEST_WIN_NO_FILESYSTEM_PERMS_NONE67static void test_status_cannot_resolve()68{69    scoped_test_env env;70    const path dir = env.create_dir("dir");71    const path file = env.create_file("dir/file", 42);72    const path sym = env.create_symlink("dir/file", "sym");73    permissions(dir, perms::none);74 75    const std::errc set_errc = std::errc::address_in_use;76    const std::errc perm_errc = std::errc::permission_denied;77    const std::errc name_too_long_errc = std::errc::filename_too_long;78 79    struct TestCase {80      path p;81      std::errc expect_errc;82    } const TestCases[] = {83      {file, perm_errc},84      {sym, perm_errc},85      {path(std::string(2500, 'a')), name_too_long_errc}86    };87    for (auto& TC : TestCases)88    {89        { // test non-throwing case90            std::error_code ec = std::make_error_code(set_errc);91            file_status st = status(TC.p, ec);92            assert(ErrorIs(ec, TC.expect_errc));93            assert(st.type() == file_type::none);94            assert(st.permissions() == perms::unknown);95        }96#ifndef TEST_HAS_NO_EXCEPTIONS97        { // test throwing case98            try {99                status(TC.p);100            } catch (filesystem_error const& err) {101                assert(err.path1() == TC.p);102                assert(err.path2() == "");103                assert(ErrorIs(err.code(), TC.expect_errc));104            }105        }106#endif107    }108}109#endif // TEST_WIN_NO_FILESYSTEM_PERMS_NONE110 111static void status_file_types_test()112{113    static_test_env static_env;114    scoped_test_env env;115    struct TestCase {116      path p;117      file_type expect_type;118    } cases[] = {119        {static_env.File, file_type::regular},120        {static_env.SymlinkToFile, file_type::regular},121        {static_env.Dir, file_type::directory},122        {static_env.SymlinkToDir, file_type::directory},123        // file_type::block files tested elsewhere124#ifndef _WIN32125        {static_env.CharFile, file_type::character},126#endif127#if !defined(__APPLE__) && !defined(__FreeBSD__) && !defined(_WIN32) // No support for domain sockets128        {env.create_socket("socket"), file_type::socket},129#endif130#ifndef _WIN32131        {env.create_fifo("fifo"), file_type::fifo}132#endif133    };134    for (const auto& TC : cases) {135        // test non-throwing case136        std::error_code ec = std::make_error_code(std::errc::address_in_use);137        file_status st = status(TC.p, ec);138        assert(!ec);139        assert(st.type() == TC.expect_type);140        assert(st.permissions() != perms::unknown);141        // test throwing case142        TEST_DOES_NOT_THROW(st = status(TC.p));143        assert(st.type() == TC.expect_type);144        assert(st.permissions() != perms::unknown);145    }146}147 148static void test_block_file()149{150    const path possible_paths[] = {151        "/dev/drive0", // Apple152        "/dev/sda",153        "/dev/loop0"154    };155    path p;156    for (const path& possible_p : possible_paths) {157        std::error_code ec;158        if (exists(possible_p, ec)) {159            p = possible_p;160            break;161        }162    }163    if (p == path{}) {164        // No possible path found.165        return;166    }167    // test non-throwing case168    std::error_code ec = std::make_error_code(std::errc::address_in_use);169    file_status st = status(p, ec);170    assert(!ec);171    assert(st.type() == file_type::block);172    assert(st.permissions() != perms::unknown);173    // test throwing case174    TEST_DOES_NOT_THROW(st = status(p));175    assert(st.type() == file_type::block);176    assert(st.permissions() != perms::unknown);177}178 179int main(int, char**) {180    signature_test();181    test_status_not_found();182#ifndef TEST_WIN_NO_FILESYSTEM_PERMS_NONE183    test_status_cannot_resolve();184#endif185    status_file_types_test();186    test_block_file();187 188    return 0;189}190