]>
git.ipfire.org Git - thirdparty/gcc.git/blob - libstdc++-v3/testsuite/27_io/filesystem/operations/copy.cc
1 // { dg-do run { target c++17 } }
2 // { dg-require-filesystem-ts "" }
4 // Copyright (C) 2014-2023 Free Software Foundation, Inc.
6 // This file is part of the GNU ISO C++ Library. This library is free
7 // software; you can redistribute it and/or modify it under the
8 // terms of the GNU General Public License as published by the
9 // Free Software Foundation; either version 3, or (at your option)
12 // This library is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 // GNU General Public License for more details.
17 // You should have received a copy of the GNU General Public License along
18 // with this library; see the file COPYING3. If not see
19 // <http://www.gnu.org/licenses/>.
21 // 15.3 Copy [fs.op.copy]
24 #include <testsuite_fs.h>
25 #include <testsuite_hooks.h>
27 namespace fs
= std::filesystem
;
29 // Test error conditions.
33 auto p
= __gnu_test::nonexistent_path();
36 VERIFY( !fs::exists(p
) );
37 fs::copy(p
, ".", fs::copy_options::none
, ec
);
41 fs::copy(".", ".", fs::copy_options::none
, ec
);
44 __gnu_test::scoped_file
f(p
);
45 VERIFY( fs::is_directory(".") );
46 VERIFY( fs::is_regular_file(p
) );
48 fs::copy(".", p
, fs::copy_options::none
, ec
);
51 auto to
= __gnu_test::nonexistent_path();
53 auto opts
= fs::copy_options::create_symlinks
;
54 fs::copy("/", to
, opts
, ec
);
55 VERIFY( ec
== std::make_error_code(std::errc::is_a_directory
) );
56 VERIFY( !exists(to
) );
59 opts
|= fs::copy_options::recursive
;
60 fs::copy("/", to
, opts
, ec
);
61 VERIFY( ec
== std::make_error_code(std::errc::is_a_directory
) );
62 VERIFY( !exists(to
) );
65 // Test is_symlink(f) case.
70 const std::error_code bad_ec
= make_error_code(std::errc::invalid_argument
);
71 auto from
= __gnu_test::nonexistent_path();
75 fs::create_symlink(".", from
, ec
);
77 VERIFY( fs::exists(from
) );
79 auto to
= __gnu_test::nonexistent_path();
81 fs::copy(from
, to
, fs::copy_options::skip_symlinks
, ec
);
83 VERIFY( !fs::exists(to
) );
86 fs::copy(from
, to
, fs::copy_options::skip_symlinks
, ec
);
88 VERIFY( !fs::exists(to
) );
92 fs::copy_options::skip_symlinks
|fs::copy_options::copy_symlinks
,
95 VERIFY( !fs::exists(to
) );
98 fs::copy(from
, to
, fs::copy_options::copy_symlinks
, ec
);
100 VERIFY( fs::exists(to
) );
101 VERIFY( is_symlink(to
) );
104 fs::copy(from
, to
, fs::copy_options::copy_symlinks
, ec
);
112 // Test is_regular_file(f) case.
116 auto from
= __gnu_test::nonexistent_path();
120 VERIFY( fs::exists(from
) );
121 VERIFY( fs::file_size(from
) == 0 );
123 auto to
= __gnu_test::nonexistent_path();
125 VERIFY( fs::exists(to
) );
126 VERIFY( fs::file_size(to
) == 0 );
129 VERIFY( !fs::exists(to
) );
130 std::ofstream
{from
} << "Hello, filesystem!";
131 VERIFY( fs::file_size(from
) != 0 );
133 VERIFY( fs::exists(to
) );
134 VERIFY( fs::file_size(to
) == fs::file_size(from
) );
140 // Test is_directory(f) case.
144 const std::error_code bad_ec
= make_error_code(std::errc::invalid_argument
);
145 auto from
= __gnu_test::nonexistent_path();
148 create_directories(from
/"a/b/c");
150 auto to
= __gnu_test::nonexistent_path();
152 __gnu_test::scoped_file
f(to
);
157 __gnu_test::scoped_file
f1(from
/"a/f1");
158 std::ofstream
{f1
.path
} << "file one";
159 __gnu_test::scoped_file
f2(from
/"a/b/f2");
160 std::ofstream
{f2
.path
} << "file two";
164 VERIFY( exists(to
) && is_empty(to
) );
168 copy(from
, to
, fs::copy_options::recursive
, ec
);
170 VERIFY( exists(to
) && !is_empty(to
) );
171 VERIFY( is_regular_file(to
/"a/f1") && !is_empty(to
/"a/f1") );
172 VERIFY( file_size(from
/"a/f1") == file_size(to
/"a/f1") );
173 VERIFY( is_regular_file(to
/"a/b/f2") && !is_empty(to
/"a/b/f2") );
174 VERIFY( file_size(from
/"a/b/f2") == file_size(to
/"a/b/f2") );
175 VERIFY( is_directory(to
/"a/b/c") && is_empty(to
/"a/b/c") );
179 remove_all(from
, ec
);
187 auto to
= __gnu_test::nonexistent_path();
188 std::error_code ec
= std::make_error_code(std::errc::invalid_argument
);
190 fs::copy("/", to
, fs::copy_options::copy_symlinks
, ec
);
191 VERIFY( !ec
); // Previous value should be cleared (LWG 2683)
197 auto dir
= __gnu_test::nonexistent_path();
198 auto source
= dir
/"source";
199 auto dest
= dir
/"dest";
200 create_directories(source
/"emptydir");
201 create_directories(dest
/"emptydir");
202 std::ofstream
{source
/"file"} << 'a';
203 std::ofstream
{dest
/"file"} << 'b';
204 // PR libstdc++/99290
205 // std::filesystem::copy does not always report errors for recursion
207 copy(source
, dest
, ec
);
208 VERIFY( ec
== std::errc::file_exists
);
214 } catch (const fs::filesystem_error
& e
) {
215 VERIFY( e
.code() == std::errc::file_exists
);