summaryrefslogtreecommitdiff
path: root/libstdc++-v3/testsuite/experimental/filesystem/operations/rename.cc
diff options
context:
space:
mode:
Diffstat (limited to 'libstdc++-v3/testsuite/experimental/filesystem/operations/rename.cc')
-rw-r--r--libstdc++-v3/testsuite/experimental/filesystem/operations/rename.cc180
1 files changed, 180 insertions, 0 deletions
diff --git a/libstdc++-v3/testsuite/experimental/filesystem/operations/rename.cc b/libstdc++-v3/testsuite/experimental/filesystem/operations/rename.cc
new file mode 100644
index 00000000000..56039e7f37d
--- /dev/null
+++ b/libstdc++-v3/testsuite/experimental/filesystem/operations/rename.cc
@@ -0,0 +1,180 @@
+// Copyright (C) 2021 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 "-DUSE_FILESYSTEM_TS -lstdc++fs" }
+// { dg-do run { target c++11 } }
+// { dg-require-filesystem-ts "" }
+
+#include <experimental/filesystem>
+#include <testsuite_hooks.h>
+#include <testsuite_fs.h>
+
+namespace fs = std::experimental::filesystem;
+
+void
+test01()
+{
+ std::error_code ec;
+ const std::error_code bad_ec = make_error_code(std::errc::invalid_argument);
+
+ auto p1 = __gnu_test::nonexistent_path();
+ auto p2 = __gnu_test::nonexistent_path();
+
+ fs::rename(p1, p2, ec);
+ VERIFY( ec );
+
+ ec.clear();
+ fs::rename(p1, "", ec);
+ VERIFY( ec );
+
+ ec.clear();
+ fs::rename("", p1, ec);
+ VERIFY( ec );
+
+ ec = bad_ec;
+ std::ofstream{p1}; // create file
+ fs::rename(p1, p1, ec); // no-op
+ VERIFY( !ec );
+ VERIFY( is_regular_file(p1) );
+
+ ec.clear();
+ rename(p2, p1, ec);
+ VERIFY( ec );
+ VERIFY( is_regular_file(p1) );
+
+ ec = bad_ec;
+ fs::rename(p1, p2, ec);
+ VERIFY( !ec );
+ VERIFY( !exists(p1) );
+ VERIFY( is_regular_file(p2) );
+
+ ec = bad_ec;
+ std::ofstream{p1}; // create file
+ fs::rename(p1, p2, ec);
+ VERIFY( !ec );
+ VERIFY( !exists(p1) );
+ VERIFY( is_regular_file(p2) );
+
+ fs::remove(p2, ec);
+}
+
+void
+test_symlinks()
+{
+#if defined(__MINGW32__) || defined(__MINGW64__)
+ // No symlink support
+#else
+ std::error_code ec;
+ const std::error_code bad_ec = make_error_code(std::errc::invalid_argument);
+
+ const auto dir = __gnu_test::nonexistent_path();
+ fs::create_directory(dir);
+
+ create_symlink(dir/"nonesuch", dir/"link"); // dangling symlink
+ ec = bad_ec;
+ fs::rename(dir/"link", dir/"newlink", ec);
+ VERIFY( !ec );
+ VERIFY( !exists(symlink_status(dir/"link")) );
+ VERIFY( is_symlink(dir/"newlink") );
+
+ __gnu_test::scoped_file f(dir/"file");
+ create_symlink(dir/"file", dir/"link");
+ ec = bad_ec;
+ fs::rename(dir/"link", dir/"newerlink", ec);
+ VERIFY( !ec );
+ VERIFY( !exists(symlink_status(dir/"link")) );
+ VERIFY( is_symlink(dir/"newerlink") );
+ VERIFY( is_regular_file(dir/"file") );
+
+ fs::remove_all(dir, ec);
+ f.path.clear();
+#endif
+}
+
+void
+test_directories()
+{
+ std::error_code ec;
+ const std::error_code bad_ec = make_error_code(std::errc::invalid_argument);
+
+ const auto dir = __gnu_test::nonexistent_path();
+ fs::create_directory(dir);
+ __gnu_test::scoped_file f(dir/"file");
+ fs::create_directory(dir/"subdir");
+
+ // Rename directory.
+ ec = bad_ec;
+ fs::rename(dir/"subdir", dir/"subdir2", ec);
+ VERIFY( !ec );
+ VERIFY( is_directory(dir/"subdir2") );
+ VERIFY( !exists(dir/"subdir") );
+
+ // Cannot rename a directory to a sub-directory of itself.
+ fs::rename(dir/"subdir2", dir/"subdir2/subsubdir", ec);
+ VERIFY( ec );
+ VERIFY( is_directory(dir/"subdir2") );
+ VERIFY( !exists(dir/"subdir2"/"subsubdir") );
+
+ // Cannot rename a file to the name of an existing directory.
+ ec.clear();
+ fs::rename(dir/"file", dir/"subdir2", ec);
+ VERIFY( ec );
+ VERIFY( is_directory(dir/"subdir2") );
+ VERIFY( is_regular_file(dir/"file") );
+
+#if defined(__MINGW32__) || defined(__MINGW64__)
+ // XXX broken on Windows, see PR 98985
+#else
+ // Cannot rename a directory to the name of an existing non-directory
+ ec.clear();
+ fs::rename(dir/"subdir2", dir/"file", ec);
+ VERIFY( ec );
+ VERIFY( is_regular_file(dir/"file") );
+ VERIFY( is_directory(dir/"subdir2") );
+
+ // Cannot rename directory to the name of a non-empty directory.
+ ec.clear();
+ __gnu_test::scoped_file f2(dir/"subdir2/file");
+ fs::create_directory(dir/"subdir");
+ fs::rename(dir/"subdir", dir/"subdir2", ec);
+ VERIFY( ec );
+ VERIFY( is_directory(dir/"subdir") );
+ VERIFY( is_directory(dir/"subdir2") );
+ VERIFY( is_regular_file(dir/"subdir2/file") );
+
+ // Can rename a non-empty directory to the name of an empty directory.
+ ec = bad_ec;
+ fs::rename(dir/"subdir2", dir/"subdir", ec);
+ VERIFY( !ec );
+ VERIFY( is_directory(dir/"subdir") );
+ VERIFY( !exists(dir/"subdir2") );
+ VERIFY( is_regular_file(dir/"subdir/file") );
+ f2.path.clear();
+
+ f.path.clear();
+#endif
+
+ fs::remove_all(dir, ec);
+}
+
+int
+main()
+{
+ test01();
+ test_symlinks();
+ test_directories();
+}