diff --git a/libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.copy_file/copy_file.pass.cpp b/libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.copy_file/copy_file.pass.cpp --- a/libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.copy_file/copy_file.pass.cpp +++ b/libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.copy_file/copy_file.pass.cpp @@ -8,8 +8,6 @@ // UNSUPPORTED: c++03 -// XFAIL: LIBCXX-WINDOWS-FIXME - // The string reported on errors changed, which makes those tests fail when run // against already-released libc++'s. // XFAIL: use_system_cxx_lib && x86_64-apple-macosx10.15 @@ -114,7 +112,7 @@ TEST_REQUIRE(fs::copy_file(file, dest, ec) == true); TEST_CHECK(!ec); auto new_st = status(dest); - TEST_CHECK(new_st.permissions() == new_perms); + TEST_CHECK(new_st.permissions() == NormalizeExpectedPerms(new_perms)); } TEST_CASE(copy_dir_test) { diff --git a/libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.permissions/permissions.pass.cpp b/libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.permissions/permissions.pass.cpp --- a/libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.permissions/permissions.pass.cpp +++ b/libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.permissions/permissions.pass.cpp @@ -8,8 +8,6 @@ // UNSUPPORTED: c++03 -// XFAIL: LIBCXX-WINDOWS-FIXME - // // void permissions(const path& p, perms prms, @@ -128,18 +126,22 @@ permissions(TC.p, TC.set_perms, TC.opts, ec); TEST_CHECK(!ec); auto pp = status(TC.p).permissions(); - TEST_CHECK(pp == TC.expected); + TEST_CHECK(pp == NormalizeExpectedPerms(TC.expected)); } if (TC.opts == perm_options::replace) { std::error_code ec = GetTestEC(); permissions(TC.p, TC.set_perms, ec); TEST_CHECK(!ec); auto pp = status(TC.p).permissions(); - TEST_CHECK(pp == TC.expected); + TEST_CHECK(pp == NormalizeExpectedPerms(TC.expected)); } } } +#ifndef _WIN32 +// This test isn't currently meaningful on Windows; the Windows file +// permissions visible via std::filesystem doesn't show any difference +// between owner/group/others. TEST_CASE(test_no_resolve_symlink_on_symlink) { scoped_test_env env; @@ -182,5 +184,6 @@ TEST_CHECK(symlink_status(sym).permissions() == expected_link_perms); } } +#endif TEST_SUITE_END() diff --git a/libcxx/test/support/filesystem_test_helper.h b/libcxx/test/support/filesystem_test_helper.h --- a/libcxx/test/support/filesystem_test_helper.h +++ b/libcxx/test/support/filesystem_test_helper.h @@ -600,6 +600,23 @@ return LHS.native() == RHS.native(); } +inline fs::perms NormalizeExpectedPerms(fs::perms P) { +#ifdef _WIN32 + // On Windows, fs::perms only maps down to one bit stored in the filesystem, + // a boolean readonly flag. + // Normalize permissions to the format it gets returned; all fs entries are + // read+exec for all users; writable ones also have the write bit set for + // all users. + P |= fs::perms::owner_read | fs::perms::group_read | fs::perms::others_read; + P |= fs::perms::owner_exec | fs::perms::group_exec | fs::perms::others_exec; + fs::perms Write = + fs::perms::owner_write | fs::perms::group_write | fs::perms::others_write; + if ((P & Write) != fs::perms::none) + P |= Write; +#endif + return P; +} + struct ExceptionChecker { std::errc expected_err; fs::path expected_path1;