]> git.ipfire.org Git - thirdparty/gcc.git/blob - libstdc++-v3/testsuite/experimental/filesystem/operations/rename.cc
Update copyright years.
[thirdparty/gcc.git] / libstdc++-v3 / testsuite / experimental / filesystem / operations / rename.cc
1 // Copyright (C) 2021-2024 Free Software Foundation, Inc.
2 //
3 // This file is part of the GNU ISO C++ Library. This library is free
4 // software; you can redistribute it and/or modify it under the
5 // terms of the GNU General Public License as published by the
6 // Free Software Foundation; either version 3, or (at your option)
7 // any later version.
8
9 // This library is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
13
14 // You should have received a copy of the GNU General Public License along
15 // with this library; see the file COPYING3. If not see
16 // <http://www.gnu.org/licenses/>.
17
18 // { dg-options "-DUSE_FILESYSTEM_TS -lstdc++fs" }
19 // { dg-do run { target c++11 } }
20 // { dg-require-filesystem-ts "" }
21 // { dg-xfail-run-if "rename is not POSIX-compliant" { *-*-rtems* } }
22
23 #include <experimental/filesystem>
24 #include <testsuite_hooks.h>
25 #include <testsuite_fs.h>
26
27 namespace fs = std::experimental::filesystem;
28
29 void
30 test01()
31 {
32 std::error_code ec;
33 const std::error_code bad_ec = make_error_code(std::errc::invalid_argument);
34
35 auto p1 = __gnu_test::nonexistent_path();
36 auto p2 = __gnu_test::nonexistent_path();
37
38 fs::rename(p1, p2, ec);
39 VERIFY( ec );
40
41 ec.clear();
42 fs::rename(p1, "", ec);
43 VERIFY( ec );
44
45 ec.clear();
46 fs::rename("", p1, ec);
47 VERIFY( ec );
48
49 ec = bad_ec;
50 std::ofstream{p1}; // create file
51 fs::rename(p1, p1, ec); // no-op
52 VERIFY( !ec );
53 VERIFY( is_regular_file(p1) );
54
55 ec.clear();
56 rename(p2, p1, ec);
57 VERIFY( ec );
58 VERIFY( is_regular_file(p1) );
59
60 ec = bad_ec;
61 fs::rename(p1, p2, ec);
62 VERIFY( !ec );
63 VERIFY( !exists(p1) );
64 VERIFY( is_regular_file(p2) );
65
66 ec = bad_ec;
67 std::ofstream{p1}; // create file
68 fs::rename(p1, p2, ec);
69 VERIFY( !ec );
70 VERIFY( !exists(p1) );
71 VERIFY( is_regular_file(p2) );
72
73 fs::remove(p2, ec);
74 }
75
76 void
77 test_symlinks()
78 {
79 #ifndef NO_SYMLINKS
80 std::error_code ec;
81 const std::error_code bad_ec = make_error_code(std::errc::invalid_argument);
82
83 const auto dir = __gnu_test::nonexistent_path();
84 fs::create_directory(dir);
85
86 create_symlink(dir/"nonesuch", dir/"link"); // dangling symlink
87 ec = bad_ec;
88 fs::rename(dir/"link", dir/"newlink", ec);
89 VERIFY( !ec );
90 VERIFY( !exists(symlink_status(dir/"link")) );
91 VERIFY( is_symlink(dir/"newlink") );
92
93 __gnu_test::scoped_file f(dir/"file");
94 create_symlink(dir/"file", dir/"link");
95 ec = bad_ec;
96 fs::rename(dir/"link", dir/"newerlink", ec);
97 VERIFY( !ec );
98 VERIFY( !exists(symlink_status(dir/"link")) );
99 VERIFY( is_symlink(dir/"newerlink") );
100 VERIFY( is_regular_file(dir/"file") );
101
102 fs::remove_all(dir, ec);
103 f.path.clear();
104 #endif
105 }
106
107 void
108 test_directories()
109 {
110 std::error_code ec;
111 const std::error_code bad_ec = make_error_code(std::errc::invalid_argument);
112
113 const auto dir = __gnu_test::nonexistent_path();
114 fs::create_directory(dir);
115 __gnu_test::scoped_file f(dir/"file");
116 fs::create_directory(dir/"subdir");
117
118 // Rename directory.
119 ec = bad_ec;
120 fs::rename(dir/"subdir", dir/"subdir2", ec);
121 VERIFY( !ec );
122 VERIFY( is_directory(dir/"subdir2") );
123 VERIFY( !exists(dir/"subdir") );
124
125 // Cannot rename a directory to a sub-directory of itself.
126 fs::rename(dir/"subdir2", dir/"subdir2/subsubdir", ec);
127 VERIFY( ec );
128 VERIFY( is_directory(dir/"subdir2") );
129 VERIFY( !exists(dir/"subdir2"/"subsubdir") );
130
131 // Cannot rename a file to the name of an existing directory.
132 ec.clear();
133 fs::rename(dir/"file", dir/"subdir2", ec);
134 VERIFY( ec );
135 VERIFY( is_directory(dir/"subdir2") );
136 VERIFY( is_regular_file(dir/"file") );
137
138 #if defined(__MINGW32__) || defined(__MINGW64__)
139 // XXX broken on Windows, see PR 98985
140 #else
141 // Cannot rename a directory to the name of an existing non-directory
142 ec.clear();
143 fs::rename(dir/"subdir2", dir/"file", ec);
144 VERIFY( ec );
145 VERIFY( is_regular_file(dir/"file") );
146 VERIFY( is_directory(dir/"subdir2") );
147
148 // Cannot rename directory to the name of a non-empty directory.
149 ec.clear();
150 __gnu_test::scoped_file f2(dir/"subdir2/file");
151 fs::create_directory(dir/"subdir");
152 fs::rename(dir/"subdir", dir/"subdir2", ec);
153 VERIFY( ec );
154 VERIFY( is_directory(dir/"subdir") );
155 VERIFY( is_directory(dir/"subdir2") );
156 VERIFY( is_regular_file(dir/"subdir2/file") );
157
158 // Can rename a non-empty directory to the name of an empty directory.
159 ec = bad_ec;
160 fs::rename(dir/"subdir2", dir/"subdir", ec);
161 VERIFY( !ec );
162 VERIFY( is_directory(dir/"subdir") );
163 VERIFY( !exists(dir/"subdir2") );
164 VERIFY( is_regular_file(dir/"subdir/file") );
165 f2.path.clear();
166
167 f.path.clear();
168 #endif
169
170 fs::remove_all(dir, ec);
171 }
172
173 int
174 main()
175 {
176 test01();
177 test_symlinks();
178 test_directories();
179 }