[libcxx-commits] [libcxx] e69c65d - [libcxx] Test accessing a directory on windows that gives "access denied" errors
Martin Storsjö via libcxx-commits
libcxx-commits at lists.llvm.org
Thu Mar 11 11:08:11 PST 2021
Author: Martin Storsjö
Date: 2021-03-11T21:07:29+02:00
New Revision: e69c65d5c45557e140b13237448581d28bbd5846
URL: https://github.com/llvm/llvm-project/commit/e69c65d5c45557e140b13237448581d28bbd5846
DIFF: https://github.com/llvm/llvm-project/commit/e69c65d5c45557e140b13237448581d28bbd5846.diff
LOG: [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
Added:
Modified:
libcxx/src/filesystem/directory_iterator.cpp
libcxx/test/std/input.output/filesystems/class.directory_entry/directory_entry.cons/path.pass.cpp
libcxx/test/std/input.output/filesystems/class.directory_iterator/directory_iterator.members/ctor.pass.cpp
libcxx/test/std/input.output/filesystems/class.rec.dir.itr/rec.dir.itr.members/ctor.pass.cpp
libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.exists/exists.pass.cpp
libcxx/test/support/filesystem_test_helper.h
Removed:
################################################################################
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 @@ class __dir_stream {
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 d23080a0a7d1..a116d0886dd4 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));
}
#ifndef _WIN32
diff --git a/libcxx/test/support/filesystem_test_helper.h b/libcxx/test/support/filesystem_test_helper.h
index e12aa9956c0c..32d2b6ab6a86 100644
--- a/libcxx/test/support/filesystem_test_helper.h
+++ b/libcxx/test/support/filesystem_test_helper.h
@@ -671,4 +671,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 */
More information about the libcxx-commits
mailing list