1 //===----------------------------------------------------------------------===//
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-exception
7 //===----------------------------------------------------------------------===//
9 // REQUIRES: can-create-symlinks
10 // UNSUPPORTED: c++03, c++11, c++14
11 // UNSUPPORTED: no-filesystem
12 // UNSUPPORTED: availability-filesystem-missing
14 // Starting in Android N (API 24), SELinux policy prevents the shell user from
15 // creating a FIFO file.
16 // XFAIL: LIBCXX-ANDROID-FIXME && !android-device-api={{21|22|23}}
20 // file_status status(const path& p);
21 // file_status status(const path& p, error_code& ec) noexcept;
25 #include "assert_macros.h"
26 #include "test_macros.h"
27 #include "filesystem_test_helper.h"
28 namespace fs
= std::filesystem
;
31 static void signature_test()
33 const path p
; ((void)p
);
34 std::error_code ec
; ((void)ec
);
35 ASSERT_NOT_NOEXCEPT(status(p
));
36 ASSERT_NOEXCEPT(status(p
, ec
));
39 static void test_status_not_found()
41 static_test_env static_env
;
42 const std::errc expect_errc
= std::errc::no_such_file_or_directory
;
47 for (auto& p
: cases
) {
48 std::error_code ec
= std::make_error_code(std::errc::address_in_use
);
49 // test non-throwing overload.
50 file_status st
= status(p
, ec
);
51 assert(ErrorIs(ec
, expect_errc
));
52 assert(st
.type() == file_type::not_found
);
53 assert(st
.permissions() == perms::unknown
);
54 // test throwing overload. It should not throw even though it reports
55 // that the file was not found.
56 TEST_DOES_NOT_THROW(st
= status(p
));
57 assert(st
.type() == file_type::not_found
);
58 assert(st
.permissions() == perms::unknown
);
62 // Windows doesn't support setting perms::none to trigger failures
63 // reading directories. Imaginary files under GetWindowsInaccessibleDir()
64 // produce no_such_file_or_directory, not the error codes this test checks
65 // for. Finally, status() for a too long file name doesn't return errors
67 #ifndef TEST_WIN_NO_FILESYSTEM_PERMS_NONE
68 static void test_status_cannot_resolve()
71 const path dir
= env
.create_dir("dir");
72 const path file
= env
.create_file("dir/file", 42);
73 const path sym
= env
.create_symlink("dir/file", "sym");
74 permissions(dir
, perms::none
);
76 const std::errc set_errc
= std::errc::address_in_use
;
77 const std::errc perm_errc
= std::errc::permission_denied
;
78 const std::errc name_too_long_errc
= std::errc::filename_too_long
;
82 std::errc expect_errc
;
83 } const TestCases
[] = {
86 {path(std::string(2500, 'a')), name_too_long_errc
}
88 for (auto& TC
: TestCases
)
90 { // test non-throwing case
91 std::error_code ec
= std::make_error_code(set_errc
);
92 file_status st
= status(TC
.p
, ec
);
93 assert(ErrorIs(ec
, TC
.expect_errc
));
94 assert(st
.type() == file_type::none
);
95 assert(st
.permissions() == perms::unknown
);
97 #ifndef TEST_HAS_NO_EXCEPTIONS
98 { // test throwing case
101 } catch (filesystem_error
const& err
) {
102 assert(err
.path1() == TC
.p
);
103 assert(err
.path2() == "");
104 assert(ErrorIs(err
.code(), TC
.expect_errc
));
110 #endif // TEST_WIN_NO_FILESYSTEM_PERMS_NONE
112 static void status_file_types_test()
114 static_test_env static_env
;
118 file_type expect_type
;
120 {static_env
.File
, file_type::regular
},
121 {static_env
.SymlinkToFile
, file_type::regular
},
122 {static_env
.Dir
, file_type::directory
},
123 {static_env
.SymlinkToDir
, file_type::directory
},
124 // file_type::block files tested elsewhere
126 {static_env
.CharFile
, file_type::character
},
128 #if !defined(__APPLE__) && !defined(__FreeBSD__) && !defined(_WIN32) // No support for domain sockets
129 {env
.create_socket("socket"), file_type::socket
},
132 {env
.create_fifo("fifo"), file_type::fifo
}
135 for (const auto& TC
: cases
) {
136 // test non-throwing case
137 std::error_code ec
= std::make_error_code(std::errc::address_in_use
);
138 file_status st
= status(TC
.p
, ec
);
140 assert(st
.type() == TC
.expect_type
);
141 assert(st
.permissions() != perms::unknown
);
142 // test throwing case
143 TEST_DOES_NOT_THROW(st
= status(TC
.p
));
144 assert(st
.type() == TC
.expect_type
);
145 assert(st
.permissions() != perms::unknown
);
149 static void test_block_file()
151 const path possible_paths
[] = {
152 "/dev/drive0", // Apple
157 for (const path
& possible_p
: possible_paths
) {
159 if (exists(possible_p
, ec
)) {
165 // No possible path found.
168 // test non-throwing case
169 std::error_code ec
= std::make_error_code(std::errc::address_in_use
);
170 file_status st
= status(p
, ec
);
172 assert(st
.type() == file_type::block
);
173 assert(st
.permissions() != perms::unknown
);
174 // test throwing case
175 TEST_DOES_NOT_THROW(st
= status(p
));
176 assert(st
.type() == file_type::block
);
177 assert(st
.permissions() != perms::unknown
);
180 int main(int, char**) {
182 test_status_not_found();
183 #ifndef TEST_WIN_NO_FILESYSTEM_PERMS_NONE
184 test_status_cannot_resolve();
186 status_file_types_test();