permissions.pass.cpp (6632B)
1 //===----------------------------------------------------------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is dual licensed under the MIT and the University of Illinois Open 6 // Source Licenses. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 // UNSUPPORTED: c++98, c++03 11 12 // <filesystem> 13 14 // void permissions(const path& p, perms prms, 15 // perm_options opts = perm_options::replace); 16 // void permissions(const path& p, perms prms, std::error_code& ec) noexcept; 17 // void permissions(const path& p, perms prms, perm_options opts, std::error_code); 18 19 20 21 #include "filesystem_include.hpp" 22 23 #include "test_macros.h" 24 #include "rapid-cxx-test.hpp" 25 #include "filesystem_test_helper.hpp" 26 27 using namespace fs; 28 29 using PR = fs::perms; 30 31 TEST_SUITE(filesystem_permissions_test_suite) 32 33 TEST_CASE(test_signatures) 34 { 35 const path p; ((void)p); 36 const perms pr{}; ((void)pr); 37 const perm_options opts{}; ((void)opts); 38 std::error_code ec; ((void)ec); 39 ASSERT_NOT_NOEXCEPT(fs::permissions(p, pr)); 40 ASSERT_NOT_NOEXCEPT(fs::permissions(p, pr, opts)); 41 ASSERT_NOEXCEPT(fs::permissions(p, pr, ec)); 42 ASSERT_NOT_NOEXCEPT(fs::permissions(p, pr, opts, ec)); 43 } 44 45 TEST_CASE(test_error_reporting) 46 { 47 auto checkThrow = [](path const& f, fs::perms opts, 48 const std::error_code& ec) 49 { 50 #ifndef TEST_HAS_NO_EXCEPTIONS 51 try { 52 fs::permissions(f, opts); 53 return false; 54 } catch (filesystem_error const& err) { 55 return err.path1() == f 56 && err.path2() == "" 57 && err.code() == ec; 58 } 59 #else 60 ((void)f); ((void)opts); ((void)ec); 61 return true; 62 #endif 63 }; 64 65 scoped_test_env env; 66 const path dne = env.make_env_path("dne"); 67 const path dne_sym = env.create_symlink(dne, "dne_sym"); 68 { // !exists 69 std::error_code ec = GetTestEC(); 70 fs::permissions(dne, fs::perms{}, ec); 71 TEST_REQUIRE(ec); 72 TEST_CHECK(ec != GetTestEC()); 73 TEST_CHECK(checkThrow(dne, fs::perms{}, ec)); 74 } 75 { 76 std::error_code ec = GetTestEC(); 77 fs::permissions(dne_sym, fs::perms{}, ec); 78 TEST_REQUIRE(ec); 79 TEST_CHECK(ec != GetTestEC()); 80 TEST_CHECK(checkThrow(dne_sym, fs::perms{}, ec)); 81 } 82 } 83 84 TEST_CASE(basic_permissions_test) 85 { 86 scoped_test_env env; 87 const path file = env.create_file("file1", 42); 88 const path dir = env.create_dir("dir1"); 89 const path file_for_sym = env.create_file("file2", 42); 90 const path sym = env.create_symlink(file_for_sym, "sym"); 91 const perm_options AP = perm_options::add; 92 const perm_options RP = perm_options::remove; 93 const perm_options NF = perm_options::nofollow; 94 struct TestCase { 95 path p; 96 perms set_perms; 97 perms expected; 98 perm_options opts; 99 TestCase(path xp, perms xperms, perms xexpect, 100 perm_options xopts = perm_options::replace) 101 : p(xp), set_perms(xperms), expected(xexpect), opts(xopts) {} 102 } cases[] = { 103 // test file 104 {file, perms::none, perms::none}, 105 {file, perms::owner_all, perms::owner_all}, 106 {file, perms::group_all, perms::owner_all | perms::group_all, AP}, 107 {file, perms::group_all, perms::owner_all, RP}, 108 // test directory 109 {dir, perms::none, perms::none}, 110 {dir, perms::owner_all, perms::owner_all}, 111 {dir, perms::group_all, perms::owner_all | perms::group_all, AP}, 112 {dir, perms::group_all, perms::owner_all, RP}, 113 // test symlink without symlink_nofollow 114 {sym, perms::none, perms::none}, 115 {sym, perms::owner_all, perms::owner_all}, 116 {sym, perms::group_all, perms::owner_all | perms::group_all, AP}, 117 {sym, perms::group_all, perms::owner_all, RP}, 118 // test non-symlink with symlink_nofollow. The last test on file/dir 119 // will have set their permissions to perms::owner_all 120 {file, perms::group_all, perms::owner_all | perms::group_all, AP | NF}, 121 {dir, perms::group_all, perms::owner_all | perms::group_all, AP | NF} 122 }; 123 for (auto const& TC : cases) { 124 TEST_CHECK(status(TC.p).permissions() != TC.expected); 125 { 126 std::error_code ec = GetTestEC(); 127 permissions(TC.p, TC.set_perms, TC.opts, ec); 128 TEST_CHECK(!ec); 129 auto pp = status(TC.p).permissions(); 130 TEST_CHECK(pp == TC.expected); 131 } 132 if (TC.opts == perm_options::replace) { 133 std::error_code ec = GetTestEC(); 134 permissions(TC.p, TC.set_perms, ec); 135 TEST_CHECK(!ec); 136 auto pp = status(TC.p).permissions(); 137 TEST_CHECK(pp == TC.expected); 138 } 139 } 140 } 141 142 TEST_CASE(test_no_resolve_symlink_on_symlink) 143 { 144 scoped_test_env env; 145 const path file = env.create_file("file", 42); 146 const path sym = env.create_symlink(file, "sym"); 147 const auto file_perms = status(file).permissions(); 148 149 struct TestCase { 150 perms set_perms; 151 perms expected; // only expected on platform that support symlink perms. 152 perm_options opts = perm_options::replace; 153 TestCase(perms xperms, perms xexpect, 154 perm_options xopts = perm_options::replace) 155 : set_perms(xperms), expected(xexpect), opts(xopts) {} 156 } cases[] = { 157 {perms::owner_all, perms::owner_all}, 158 {perms::group_all, perms::owner_all | perms::group_all, perm_options::add}, 159 {perms::owner_all, perms::group_all, perm_options::remove}, 160 }; 161 for (auto const& TC : cases) { 162 #if defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__) 163 // On OS X symlink permissions are supported. We should get an empty 164 // error code and the expected permissions. 165 const auto expected_link_perms = TC.expected; 166 std::error_code expected_ec; 167 #else 168 // On linux symlink permissions are not supported. The error code should 169 // be 'operation_not_supported' and the symlink permissions should be 170 // unchanged. 171 const auto expected_link_perms = symlink_status(sym).permissions(); 172 std::error_code expected_ec = std::make_error_code(std::errc::operation_not_supported); 173 #endif 174 std::error_code ec = GetTestEC(); 175 permissions(sym, TC.set_perms, TC.opts | perm_options::nofollow, ec); 176 TEST_CHECK(ec == expected_ec); 177 TEST_CHECK(status(file).permissions() == file_perms); 178 TEST_CHECK(symlink_status(sym).permissions() == expected_link_perms); 179 } 180 } 181 182 TEST_SUITE_END()