Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / libcxx / test / std / input.output / filesystems / fs.op.funcs / fs.op.symlink_status / symlink_status.pass.cpp
blob81e8389fb2fa7c8669c6f110e2063ee54a20effa
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-exception
6 //
7 //===----------------------------------------------------------------------===//
9 // UNSUPPORTED: c++03
10 // UNSUPPORTED: no-filesystem
11 // UNSUPPORTED: availability-filesystem-missing
13 // Starting in Android N (API 24), SELinux policy prevents the shell user from
14 // creating a FIFO file.
15 // XFAIL: LIBCXX-ANDROID-FIXME && !android-device-api={{21|22|23}}
17 // <filesystem>
19 // file_status symlink_status(const path& p);
20 // file_status symlink_status(const path& p, error_code& ec) noexcept;
22 #include "filesystem_include.h"
24 #include "assert_macros.h"
25 #include "test_macros.h"
26 #include "filesystem_test_helper.h"
28 using namespace fs;
30 static void signature_test()
32 const path p; ((void)p);
33 std::error_code ec; ((void)ec);
34 ASSERT_NOT_NOEXCEPT(symlink_status(p));
35 ASSERT_NOEXCEPT(symlink_status(p, ec));
38 static void test_symlink_status_not_found()
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
45 for (auto& p : cases) {
46 std::error_code ec = std::make_error_code(std::errc::address_in_use);
47 // test non-throwing overload.
48 file_status st = symlink_status(p, ec);
49 assert(ErrorIs(ec, expect_errc));
50 assert(st.type() == file_type::not_found);
51 assert(st.permissions() == perms::unknown);
52 // test throwing overload. It should not throw even though it reports
53 // that the file was not found.
54 TEST_DOES_NOT_THROW(st = status(p));
55 assert(st.type() == file_type::not_found);
56 assert(st.permissions() == perms::unknown);
60 // Windows doesn't support setting perms::none to trigger failures
61 // reading directories. Imaginary files under GetWindowsInaccessibleDir()
62 // produce no_such_file_or_directory, not the error codes this test checks
63 // for. Finally, status() for a too long file name doesn't return errors
64 // on windows.
65 #ifndef TEST_WIN_NO_FILESYSTEM_PERMS_NONE
66 static void test_symlink_status_cannot_resolve()
68 scoped_test_env env;
69 const path dir = env.create_dir("dir");
70 const path file_in_dir = env.create_file("dir/file", 42);
71 const path sym_in_dir = env.create_symlink("dir/file", "dir/bad_sym");
72 const path sym_points_in_dir = env.create_symlink("dir/file", "sym");
73 permissions(dir, perms::none);
75 const std::errc set_errc = std::errc::address_in_use;
76 const std::errc expect_errc = std::errc::permission_denied;
78 const path fail_cases[] = {
79 file_in_dir, sym_in_dir
81 for (auto& p : fail_cases)
83 { // test non-throwing case
84 std::error_code ec = std::make_error_code(set_errc);
85 file_status st = symlink_status(p, ec);
86 assert(ErrorIs(ec, expect_errc));
87 assert(st.type() == file_type::none);
88 assert(st.permissions() == perms::unknown);
90 #ifndef TEST_HAS_NO_EXCEPTIONS
91 { // test throwing case
92 try {
93 (void)symlink_status(p);
94 } catch (filesystem_error const& err) {
95 assert(err.path1() == p);
96 assert(err.path2() == "");
97 assert(ErrorIs(err.code(), expect_errc));
100 #endif
102 // Test that a symlink that points into a directory without read perms
103 // can be stat-ed using symlink_status
105 std::error_code ec = std::make_error_code(set_errc);
106 file_status st = symlink_status(sym_points_in_dir, ec);
107 assert(!ec);
108 assert(st.type() == file_type::symlink);
109 assert(st.permissions() != perms::unknown);
110 // test non-throwing version
111 TEST_DOES_NOT_THROW(st = symlink_status(sym_points_in_dir));
112 assert(st.type() == file_type::symlink);
113 assert(st.permissions() != perms::unknown);
116 #endif // TEST_WIN_NO_FILESYSTEM_PERMS_NONE
119 static void symlink_status_file_types_test()
121 static_test_env static_env;
122 scoped_test_env env;
123 struct TestCase {
124 path p;
125 file_type expect_type;
126 } cases[] = {
127 {static_env.BadSymlink, file_type::symlink},
128 {static_env.File, file_type::regular},
129 {static_env.SymlinkToFile, file_type::symlink},
130 {static_env.Dir, file_type::directory},
131 {static_env.SymlinkToDir, file_type::symlink},
132 // file_type::block files tested elsewhere
133 #ifndef _WIN32
134 {static_env.CharFile, file_type::character},
135 #endif
136 #if !defined(__APPLE__) && !defined(__FreeBSD__) && !defined(_WIN32) // No support for domain sockets
137 {env.create_socket("socket"), file_type::socket},
138 #endif
139 #ifndef _WIN32
140 {env.create_fifo("fifo"), file_type::fifo}
141 #endif
143 for (const auto& TC : cases) {
144 // test non-throwing case
145 std::error_code ec = std::make_error_code(std::errc::address_in_use);
146 file_status st = symlink_status(TC.p, ec);
147 assert(!ec);
148 assert(st.type() == TC.expect_type);
149 assert(st.permissions() != perms::unknown);
150 // test throwing case
151 TEST_DOES_NOT_THROW(st = symlink_status(TC.p));
152 assert(st.type() == TC.expect_type);
153 assert(st.permissions() != perms::unknown);
157 static void test_block_file()
159 const path possible_paths[] = {
160 "/dev/drive0", // Apple
161 "/dev/sda", // Linux
162 "/dev/loop0" // Linux
163 // No FreeBSD files known
165 path p;
166 for (const path& possible_p : possible_paths) {
167 std::error_code ec;
168 if (exists(possible_p, ec)) {
169 p = possible_p;
170 break;
173 if (p == path{}) {
174 // No possible path found.
175 return;
177 scoped_test_env env;
178 { // test block file
179 // test non-throwing case
180 std::error_code ec = std::make_error_code(std::errc::address_in_use);
181 file_status st = symlink_status(p, ec);
182 assert(!ec);
183 assert(st.type() == file_type::block);
184 assert(st.permissions() != perms::unknown);
185 // test throwing case
186 TEST_DOES_NOT_THROW(st = symlink_status(p));
187 assert(st.type() == file_type::block);
188 assert(st.permissions() != perms::unknown);
190 const path sym = env.make_env_path("sym");
191 create_symlink(p, sym);
192 { // test symlink to block file
193 // test non-throwing case
194 std::error_code ec = std::make_error_code(std::errc::address_in_use);
195 file_status st = symlink_status(sym, ec);
196 assert(!ec);
197 assert(st.type() == file_type::symlink);
198 assert(st.permissions() != perms::unknown);
199 // test throwing case
200 TEST_DOES_NOT_THROW(st = symlink_status(sym));
201 assert(st.type() == file_type::symlink);
202 assert(st.permissions() != perms::unknown);
206 int main(int, char**) {
207 signature_test();
208 test_symlink_status_not_found();
209 #ifndef TEST_WIN_NO_FILESYSTEM_PERMS_NONE
210 test_symlink_status_cannot_resolve();
211 #endif
212 symlink_status_file_types_test();
213 test_block_file();
214 return 0;