aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathan Wakely <jwakely@redhat.com>2016-05-10 14:04:21 +0100
committerJonathan Wakely <redi@gcc.gnu.org>2016-05-10 14:04:21 +0100
commitf9a39467b6a282bc7fba47fd8cf1e44413e7508f (patch)
treeb0b5ace8f7cf34e0f069359df6dc21b5023946eb
parent927d22fa017bb0bdfcb221e64f13b4e548f697aa (diff)
downloadgcc-f9a39467b6a282bc7fba47fd8cf1e44413e7508f.zip
gcc-f9a39467b6a282bc7fba47fd8cf1e44413e7508f.tar.gz
gcc-f9a39467b6a282bc7fba47fd8cf1e44413e7508f.tar.bz2
libstdc++/71036 Handle EEXIST in filesystem::create_directory
PR libstdc++/71036 * src/filesystem/ops.cc (create_dir): Handle EEXIST from mkdir. * testsuite/experimental/filesystem/operations/create_directory.cc: New test. From-SVN: r236076
-rw-r--r--libstdc++-v3/ChangeLog5
-rw-r--r--libstdc++-v3/src/filesystem/ops.cc12
-rw-r--r--libstdc++-v3/testsuite/experimental/filesystem/operations/create_directory.cc63
3 files changed, 76 insertions, 4 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index cf7ce6f..20c55ff 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,5 +1,10 @@
2016-05-10 Jonathan Wakely <jwakely@redhat.com>
+ PR libstdc++/71036
+ * src/filesystem/ops.cc (create_dir): Handle EEXIST from mkdir.
+ * testsuite/experimental/filesystem/operations/create_directory.cc:
+ New test.
+
PR libstdc++/71037
* src/filesystem/ops.cc (canonical(const path&, const path&)): Add
base path to exception.
diff --git a/libstdc++-v3/src/filesystem/ops.cc b/libstdc++-v3/src/filesystem/ops.cc
index e18c751..fab4235 100644
--- a/libstdc++-v3/src/filesystem/ops.cc
+++ b/libstdc++-v3/src/filesystem/ops.cc
@@ -660,22 +660,26 @@ namespace
bool
create_dir(const fs::path& p, fs::perms perm, std::error_code& ec)
{
+ bool created = false;
#ifdef _GLIBCXX_HAVE_SYS_STAT_H
::mode_t mode = static_cast<std::underlying_type_t<fs::perms>>(perm);
if (::mkdir(p.c_str(), mode))
{
- ec.assign(errno, std::generic_category());
- return false;
+ const int err = errno;
+ if (err != EEXIST || !is_directory(p))
+ ec.assign(err, std::generic_category());
+ else
+ ec.clear();
}
else
{
ec.clear();
- return true;
+ created = true;
}
#else
ec = std::make_error_code(std::errc::not_supported);
- return false;
#endif
+ return created;
}
} // namespace
diff --git a/libstdc++-v3/testsuite/experimental/filesystem/operations/create_directory.cc b/libstdc++-v3/testsuite/experimental/filesystem/operations/create_directory.cc
new file mode 100644
index 0000000..66c2b3f
--- /dev/null
+++ b/libstdc++-v3/testsuite/experimental/filesystem/operations/create_directory.cc
@@ -0,0 +1,63 @@
+// Copyright (C) 2016 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++11 -lstdc++fs" }
+// { dg-require-filesystem-ts "" }
+
+#include <experimental/filesystem>
+#include <testsuite_hooks.h>
+#include <testsuite_fs.h>
+
+namespace fs = std::experimental::filesystem;
+
+void
+test01()
+{
+ bool test __attribute__((unused)) = false;
+ std::error_code ec;
+
+ // Test empty path.
+ fs::path p;
+ bool b = create_directory( p, ec );
+ VERIFY( ec );
+ VERIFY( !b );
+
+ // Test non-existent path
+ p = __gnu_test::nonexistent_path();
+ VERIFY( !exists(p) );
+
+ b = create_directory(p, ec); // create the directory once
+ VERIFY( !ec );
+ VERIFY( b );
+ VERIFY( exists(p) );
+
+ // Test existing path (libstdc++/71036).
+ b = create_directory(p, ec);
+ VERIFY( !ec );
+ VERIFY( !b );
+ b = create_directory(p);
+ VERIFY( !ec );
+ VERIFY( !b );
+
+ remove_all(p, ec);
+}
+
+int
+main()
+{
+ test01();
+}