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.
198 lines
8.0 KiB
Diff
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
|
|
|