summaryrefslogtreecommitdiff
path: root/libstdc++-v3
diff options
context:
space:
mode:
authorJonathan Wakely <jwakely@redhat.com>2016-10-24 17:45:51 +0100
committerJonathan Wakely <redi@gcc.gnu.org>2016-10-24 17:45:51 +0100
commit6daff2d946a2a656b5796e00d6ad65660315d565 (patch)
tree2fdbe7c11d477c3df27aa4e6f0894e21230764f5 /libstdc++-v3
parentbb52a7e324258d55eef28d2b1c473b3973507da2 (diff)
PR71337 fix filesystem::temp_directory_path error handling
PR libstdc++/71337 * src/filesystem/ops.cc (temp_directory_path): Pass error_code argument to other filesystem operations. * testsuite/experimental/filesystem/operations/temp_directory_path.cc: Add testcase for inaccessible directory. From-SVN: r241487
Diffstat (limited to 'libstdc++-v3')
-rw-r--r--libstdc++-v3/ChangeLog6
-rw-r--r--libstdc++-v3/src/filesystem/ops.cc13
-rw-r--r--libstdc++-v3/testsuite/experimental/filesystem/operations/temp_directory_path.cc46
3 files changed, 61 insertions, 4 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index 7c65fb04881..bc9a215e20a 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,5 +1,11 @@
2016-10-24 Jonathan Wakely <jwakely@redhat.com>
+ PR libstdc++/71337
+ * src/filesystem/ops.cc (temp_directory_path): Pass error_code
+ argument to other filesystem operations.
+ * testsuite/experimental/filesystem/operations/temp_directory_path.cc:
+ Add testcase for inaccessible directory.
+
* src/filesystem/dir.cc (open_dir): Return same value for errors
whether ignored or not.
(_Dir::advance(error_code*, directory_options)): Return false on
diff --git a/libstdc++-v3/src/filesystem/ops.cc b/libstdc++-v3/src/filesystem/ops.cc
index f8ba74ecbb3..90c225b0339 100644
--- a/libstdc++-v3/src/filesystem/ops.cc
+++ b/libstdc++-v3/src/filesystem/ops.cc
@@ -1428,12 +1428,17 @@ fs::path fs::temp_directory_path(error_code& ec)
for (auto e = env; tmpdir == nullptr && *e != nullptr; ++e)
tmpdir = ::getenv(*e);
path p = tmpdir ? tmpdir : "/tmp";
- if (exists(p) && is_directory(p))
+ auto st = status(p, ec);
+ if (!ec)
{
- ec.clear();
- return p;
+ if (is_directory(st))
+ {
+ ec.clear();
+ return p;
+ }
+ else
+ ec = std::make_error_code(std::errc::not_a_directory);
}
- ec = std::make_error_code(std::errc::not_a_directory);
return {};
#endif
}
diff --git a/libstdc++-v3/testsuite/experimental/filesystem/operations/temp_directory_path.cc b/libstdc++-v3/testsuite/experimental/filesystem/operations/temp_directory_path.cc
index 6e202c98dde..7f7e9fd7f26 100644
--- a/libstdc++-v3/testsuite/experimental/filesystem/operations/temp_directory_path.cc
+++ b/libstdc++-v3/testsuite/experimental/filesystem/operations/temp_directory_path.cc
@@ -45,6 +45,7 @@ test01()
std::error_code ec;
fs::path p1 = fs::temp_directory_path(ec);
+ VERIFY( !ec );
VERIFY( exists(p1) );
fs::path p2 = fs::temp_directory_path();
@@ -62,6 +63,7 @@ test02()
std::error_code ec;
fs::path p = fs::temp_directory_path(ec);
VERIFY( ec );
+ VERIFY( p == fs::path() );
std::error_code ec2;
try {
@@ -72,10 +74,54 @@ test02()
VERIFY( ec2 == ec );
}
+void
+test03()
+{
+ auto p = __gnu_test::nonexistent_path();
+ create_directories(p/"tmp");
+ permissions(p, fs::perms::none);
+ setenv("TMPDIR", (p/"tmp").c_str(), 1);
+ std::error_code ec;
+ auto r = fs::temp_directory_path(ec); // libstdc++/PR71337
+ VERIFY( ec == std::make_error_code(std::errc::permission_denied) );
+ VERIFY( r == fs::path() );
+
+ std::error_code ec2;
+ try {
+ fs::temp_directory_path();
+ } catch (const fs::filesystem_error& e) {
+ ec2 = e.code();
+ }
+ VERIFY( ec2 == ec );
+
+ permissions(p, fs::perms::owner_all, ec);
+ remove_all(p, ec);
+}
+
+void
+test04()
+{
+ __gnu_test::scoped_file f;
+ setenv("TMPDIR", f.path.c_str(), 1);
+ std::error_code ec;
+ auto r = fs::temp_directory_path(ec);
+ VERIFY( ec == std::make_error_code(std::errc::not_a_directory) );
+ VERIFY( r == fs::path() );
+
+ std::error_code ec2;
+ try {
+ fs::temp_directory_path();
+ } catch (const fs::filesystem_error& e) {
+ ec2 = e.code();
+ }
+ VERIFY( ec2 == ec );
+}
int
main()
{
test01();
test02();
+ test03();
+ test04();
}