Files
llvm-mingw/patches/llvm-project/0023-libcxx-Test-accessing-a-directory-on-windows-that-gi.patch
T
Martin Storsjö 657d12c8a5 Backport another libc++ patch for std::filesystem (and locale) usage
This fixes linking against a DLL of libc++ while using the common headers
(generated from the static version of the library, but which work for
both shared and static versions) when calling e.g. std::filesystem::u8path.
2021-05-25 23:55:32 +03:00

198 lines
8.0 KiB
Diff

From 9a1bb266e38b31c78de03abc2d41cdd3245595d0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Martin=20Storsj=C3=B6?= <martin@martin.st>
Date: Mon, 8 Mar 2021 12:03:30 +0200
Subject: [PATCH 23/25] [libcxx] Test accessing a directory on windows that
gives "access denied" errors
Fix handling of skip_permission_denied on windows; after converting
the return value of GetLastError() to a standard error_code, ec.value()
is in the standard errc range, not a native windows error code. This
was missed in 156180727d6c347eda3ba749730707acb8a48093.
The directory "C:\System Volume Information" does seem to exist and
have these properties on most relevant contempory setups.
Differential Revision: https://reviews.llvm.org/D98166
(cherry picked from commit e69c65d5c45557e140b13237448581d28bbd5846)
---
libcxx/src/filesystem/directory_iterator.cpp | 3 ++-
.../directory_entry.cons/path.pass.cpp | 18 +++++++++++++
.../directory_iterator.members/ctor.pass.cpp | 8 ++++++
.../rec.dir.itr.members/ctor.pass.cpp | 8 ++++++
.../fs.op.funcs/fs.op.exists/exists.pass.cpp | 14 ++++++++---
libcxx/test/support/filesystem_test_helper.h | 25 +++++++++++++++++++
6 files changed, 72 insertions(+), 4 deletions(-)
diff --git a/libcxx/src/filesystem/directory_iterator.cpp b/libcxx/src/filesystem/directory_iterator.cpp
index 2721dea5c98f..bb3653076bfc 100644
--- a/libcxx/src/filesystem/directory_iterator.cpp
+++ b/libcxx/src/filesystem/directory_iterator.cpp
@@ -124,7 +124,8 @@ public:
ec = detail::make_windows_error(GetLastError());
const bool ignore_permission_denied =
bool(opts & directory_options::skip_permission_denied);
- if (ignore_permission_denied && ec.value() == ERROR_ACCESS_DENIED)
+ if (ignore_permission_denied &&
+ ec.value() == static_cast<int>(errc::permission_denied))
ec.clear();
return;
}
diff --git a/libcxx/test/std/input.output/filesystems/class.directory_entry/directory_entry.cons/path.pass.cpp b/libcxx/test/std/input.output/filesystems/class.directory_entry/directory_entry.cons/path.pass.cpp
index e3759e22b0ba..a118fae4d54b 100644
--- a/libcxx/test/std/input.output/filesystems/class.directory_entry/directory_entry.cons/path.pass.cpp
+++ b/libcxx/test/std/input.output/filesystems/class.directory_entry/directory_entry.cons/path.pass.cpp
@@ -148,6 +148,23 @@ TEST_CASE(path_ctor_dne) {
TEST_CASE(path_ctor_cannot_resolve) {
using namespace fs;
+#ifdef _WIN32
+ // Windows doesn't support setting perms::none to trigger failures
+ // reading directories; test using a special inaccessible directory
+ // instead.
+ const path dir = GetWindowsInaccessibleDir();
+ TEST_REQUIRE(!dir.empty());
+ const path file = dir / "file";
+ {
+ std::error_code ec = GetTestEC();
+ directory_entry ent(file, ec);
+ TEST_CHECK(ErrorIs(ec, std::errc::no_such_file_or_directory));
+ TEST_CHECK(ent.path() == file);
+ }
+ {
+ TEST_CHECK_NO_THROW(directory_entry(file));
+ }
+#else
scoped_test_env env;
const path dir = env.create_dir("dir");
const path file = env.create_file("dir/file", 42);
@@ -179,6 +196,7 @@ TEST_CASE(path_ctor_cannot_resolve) {
TEST_CHECK_NO_THROW(directory_entry(sym_in_dir));
TEST_CHECK_NO_THROW(directory_entry(sym_out_of_dir));
}
+#endif
}
TEST_SUITE_END()
diff --git a/libcxx/test/std/input.output/filesystems/class.directory_iterator/directory_iterator.members/ctor.pass.cpp b/libcxx/test/std/input.output/filesystems/class.directory_iterator/directory_iterator.members/ctor.pass.cpp
index 48cf72a77b05..fae696613c75 100644
--- a/libcxx/test/std/input.output/filesystems/class.directory_iterator/directory_iterator.members/ctor.pass.cpp
+++ b/libcxx/test/std/input.output/filesystems/class.directory_iterator/directory_iterator.members/ctor.pass.cpp
@@ -87,6 +87,13 @@ TEST_CASE(test_construction_from_bad_path)
TEST_CASE(access_denied_test_case)
{
using namespace fs;
+#ifdef _WIN32
+ // Windows doesn't support setting perms::none to trigger failures
+ // reading directories; test using a special inaccessible directory
+ // instead.
+ const path testDir = GetWindowsInaccessibleDir();
+ TEST_REQUIRE(!testDir.empty());
+#else
scoped_test_env env;
path const testDir = env.make_env_path("dir1");
path const testFile = testDir / "testFile";
@@ -100,6 +107,7 @@ TEST_CASE(access_denied_test_case)
}
// Change the permissions so we can no longer iterate
permissions(testDir, perms::none);
+#endif
// Check that the construction fails when skip_permissions_denied is
// not given.
diff --git a/libcxx/test/std/input.output/filesystems/class.rec.dir.itr/rec.dir.itr.members/ctor.pass.cpp b/libcxx/test/std/input.output/filesystems/class.rec.dir.itr/rec.dir.itr.members/ctor.pass.cpp
index ddffaca39335..53ca5737ba31 100644
--- a/libcxx/test/std/input.output/filesystems/class.rec.dir.itr/rec.dir.itr.members/ctor.pass.cpp
+++ b/libcxx/test/std/input.output/filesystems/class.rec.dir.itr/rec.dir.itr.members/ctor.pass.cpp
@@ -88,6 +88,13 @@ TEST_CASE(test_construction_from_bad_path)
TEST_CASE(access_denied_test_case)
{
using namespace fs;
+#ifdef _WIN32
+ // Windows doesn't support setting perms::none to trigger failures
+ // reading directories; test using a special inaccessible directory
+ // instead.
+ const path testDir = GetWindowsInaccessibleDir();
+ TEST_REQUIRE(!testDir.empty());
+#else
scoped_test_env env;
path const testDir = env.make_env_path("dir1");
path const testFile = testDir / "testFile";
@@ -102,6 +109,7 @@ TEST_CASE(access_denied_test_case)
// Change the permissions so we can no longer iterate
permissions(testDir, perms::none);
+#endif
// Check that the construction fails when skip_permissions_denied is
// not given.
diff --git a/libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.exists/exists.pass.cpp b/libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.exists/exists.pass.cpp
index 581d9fe041a9..1b7131bbadff 100644
--- a/libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.exists/exists.pass.cpp
+++ b/libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.exists/exists.pass.cpp
@@ -73,16 +73,24 @@ TEST_CASE(test_exist_not_found)
TEST_CASE(test_exists_fails)
{
+#ifdef _WIN32
+ // Windows doesn't support setting perms::none to trigger failures
+ // reading directories; test using a special inaccessible directory
+ // instead.
+ const path p = GetWindowsInaccessibleDir();
+ TEST_REQUIRE(!p.empty());
+#else
scoped_test_env env;
const path dir = env.create_dir("dir");
- const path file = env.create_file("dir/file", 42);
+ const path p = env.create_file("dir/file", 42);
permissions(dir, perms::none);
+#endif
std::error_code ec;
- TEST_CHECK(exists(file, ec) == false);
+ TEST_CHECK(exists(p, ec) == false);
TEST_CHECK(ec);
- TEST_CHECK_THROW(filesystem_error, exists(file));
+ TEST_CHECK_THROW(filesystem_error, exists(p));
}
TEST_CASE(test_name_too_long) {
diff --git a/libcxx/test/support/filesystem_test_helper.h b/libcxx/test/support/filesystem_test_helper.h
index eeee3e935b8a..92c017f610fe 100644
--- a/libcxx/test/support/filesystem_test_helper.h
+++ b/libcxx/test/support/filesystem_test_helper.h
@@ -690,4 +690,29 @@ struct ExceptionChecker {
};
+inline fs::path GetWindowsInaccessibleDir() {
+ // Only makes sense on windows, but the code can be compiled for
+ // any platform.
+ const fs::path dir("C:\\System Volume Information");
+ std::error_code ec;
+ const fs::path root("C:\\");
+ fs::directory_iterator it(root, ec);
+ if (ec)
+ return fs::path();
+ const fs::directory_iterator endIt{};
+ while (it != endIt) {
+ const fs::directory_entry &ent = *it;
+ if (ent == dir) {
+ // Basic sanity checks on the directory_entry
+ if (!ent.exists())
+ return fs::path();
+ if (!ent.is_directory())
+ return fs::path();
+ return ent;
+ }
+ ++it;
+ }
+ return fs::path();
+}
+
#endif /* FILESYSTEM_TEST_HELPER_HPP */
--
2.25.1