PR71337 fix filesystem::temp_directory_path error handling
authorJonathan Wakely <jwakely@redhat.com>
Mon, 24 Oct 2016 16:45:51 +0000 (17:45 +0100)
committerJonathan Wakely <redi@gcc.gnu.org>
Mon, 24 Oct 2016 16:45:51 +0000 (17:45 +0100)
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

libstdc++-v3/ChangeLog
libstdc++-v3/src/filesystem/ops.cc
libstdc++-v3/testsuite/experimental/filesystem/operations/temp_directory_path.cc

index 7c65fb0488161289a575c209b726018f0e02891c..bc9a215e20a5e113f238c53811da9850b9347d40 100644 (file)
@@ -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
index f8ba74ecbb3033025b272988aa4441b31cc29888..90c225b03391fe75eaf6288049eb3a53d4151f3f 100644 (file)
@@ -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
 }
index 6e202c98dde1ba1e7554b196a39601c6470263d8..7f7e9fd7f26d10739293af5887170b5c75454cb8 100644 (file)
@@ -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();
 }