diff options
author | Jonathan Wakely <jwakely@redhat.com> | 2016-10-24 17:45:51 +0100 |
---|---|---|
committer | Jonathan Wakely <redi@gcc.gnu.org> | 2016-10-24 17:45:51 +0100 |
commit | 6daff2d946a2a656b5796e00d6ad65660315d565 (patch) | |
tree | 2fdbe7c11d477c3df27aa4e6f0894e21230764f5 /libstdc++-v3 | |
parent | bb52a7e324258d55eef28d2b1c473b3973507da2 (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/ChangeLog | 6 | ||||
-rw-r--r-- | libstdc++-v3/src/filesystem/ops.cc | 13 | ||||
-rw-r--r-- | libstdc++-v3/testsuite/experimental/filesystem/operations/temp_directory_path.cc | 46 |
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(); } |