[gcc r10-10833] libstdc++: Fix error reporting in filesystem::copy [PR99290]
Jonathan Wakely
redi@gcc.gnu.org
Tue Jun 14 19:20:22 GMT 2022
https://gcc.gnu.org/g:43cbff3da5a856d1b18a9ad33b337ab829af73ed
commit r10-10833-g43cbff3da5a856d1b18a9ad33b337ab829af73ed
Author: Jonathan Wakely <jwakely@redhat.com>
Date: Thu Apr 28 13:06:31 2022 +0100
libstdc++: Fix error reporting in filesystem::copy [PR99290]
The recursive calls to filesystem::copy should stop if any of them
reports an error.
libstdc++-v3/ChangeLog:
PR libstdc++/99290
* src/c++17/fs_ops.cc (fs::copy): Pass error_code to
directory_iterator constructor, and check on each iteration.
* src/filesystem/ops.cc (fs::copy): Likewise.
* testsuite/27_io/filesystem/operations/copy.cc: Check for
errors during recursion.
* testsuite/experimental/filesystem/operations/copy.cc:
Likewise.
(cherry picked from commit 4e117418fb71f508c479e0144500f4da9cc92520)
Diff:
---
libstdc++-v3/src/c++17/fs_ops.cc | 8 ++++--
libstdc++-v3/src/filesystem/ops.cc | 8 ++++--
.../testsuite/27_io/filesystem/operations/copy.cc | 29 ++++++++++++++++++++++
.../experimental/filesystem/operations/copy.cc | 29 ++++++++++++++++++++++
4 files changed, 70 insertions(+), 4 deletions(-)
diff --git a/libstdc++-v3/src/c++17/fs_ops.cc b/libstdc++-v3/src/c++17/fs_ops.cc
index 008195c2d31..5231f67561e 100644
--- a/libstdc++-v3/src/c++17/fs_ops.cc
+++ b/libstdc++-v3/src/c++17/fs_ops.cc
@@ -404,8 +404,12 @@ fs::copy(const path& from, const path& to, copy_options options,
// set an unused bit in options to disable further recursion
if (!is_set(options, copy_options::recursive))
options |= static_cast<copy_options>(4096);
- for (const directory_entry& x : directory_iterator(from))
- copy(x.path(), to/x.path().filename(), options, ec);
+ for (const directory_entry& x : directory_iterator(from, ec))
+ {
+ copy(x.path(), to/x.path().filename(), options, ec);
+ if (ec)
+ return;
+ }
}
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 2683. filesystem::copy() says "no effects"
diff --git a/libstdc++-v3/src/filesystem/ops.cc b/libstdc++-v3/src/filesystem/ops.cc
index 321eb3a5cba..e7b145f8d79 100644
--- a/libstdc++-v3/src/filesystem/ops.cc
+++ b/libstdc++-v3/src/filesystem/ops.cc
@@ -344,8 +344,12 @@ fs::copy(const path& from, const path& to, copy_options options,
// set an unused bit in options to disable further recursion
if (!is_set(options, copy_options::recursive))
options |= static_cast<copy_options>(4096);
- for (const directory_entry& x : directory_iterator(from))
- copy(x.path(), to/x.path().filename(), options, ec);
+ for (const directory_entry& x : directory_iterator(from, ec))
+ {
+ copy(x.path(), to/x.path().filename(), options, ec);
+ if (ec)
+ return;
+ }
}
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// 2683. filesystem::copy() says "no effects"
diff --git a/libstdc++-v3/testsuite/27_io/filesystem/operations/copy.cc b/libstdc++-v3/testsuite/27_io/filesystem/operations/copy.cc
index f7aac8a302f..cbd8c8ea03e 100644
--- a/libstdc++-v3/testsuite/27_io/filesystem/operations/copy.cc
+++ b/libstdc++-v3/testsuite/27_io/filesystem/operations/copy.cc
@@ -194,6 +194,34 @@ test05()
VERIFY( !ec ); // Previous value should be cleared (LWG 2683)
}
+void
+test_pr99290()
+{
+ auto dir = __gnu_test::nonexistent_path();
+ auto source = dir/"source";
+ auto dest = dir/"dest";
+ create_directories(source/"emptydir");
+ create_directories(dest/"emptydir");
+ std::ofstream{source/"file"} << 'a';
+ std::ofstream{dest/"file"} << 'b';
+ // PR libstdc++/99290
+ // std::filesystem::copy does not always report errors for recursion
+ std::error_code ec;
+ copy(source, dest, ec);
+ VERIFY( ec == std::errc::file_exists );
+
+#if __cpp_exceptions
+ try {
+ copy(source, dest);
+ VERIFY( false );
+ } catch (const fs::filesystem_error& e) {
+ VERIFY( e.code() == std::errc::file_exists );
+ }
+#endif
+
+ remove_all(dir);
+}
+
int
main()
{
@@ -202,4 +230,5 @@ main()
test03();
test04();
test05();
+ test_pr99290();
}
diff --git a/libstdc++-v3/testsuite/experimental/filesystem/operations/copy.cc b/libstdc++-v3/testsuite/experimental/filesystem/operations/copy.cc
index e1e6d1dcc15..75f7e0d8297 100644
--- a/libstdc++-v3/testsuite/experimental/filesystem/operations/copy.cc
+++ b/libstdc++-v3/testsuite/experimental/filesystem/operations/copy.cc
@@ -190,6 +190,34 @@ test05()
VERIFY( !ec ); // Previous value should be cleared (LWG 2683)
}
+void
+test_pr99290()
+{
+ auto dir = __gnu_test::nonexistent_path();
+ auto source = dir/"source";
+ auto dest = dir/"dest";
+ create_directories(source/"emptydir");
+ create_directories(dest/"emptydir");
+ std::ofstream{source/"file"} << 'a';
+ std::ofstream{dest/"file"} << 'b';
+ // PR libstdc++/99290
+ // std::filesystem::copy does not always report errors for recursion
+ std::error_code ec;
+ copy(source, dest, ec);
+ VERIFY( ec == std::errc::file_exists );
+
+#if __cpp_exceptions
+ try {
+ copy(source, dest);
+ VERIFY( false );
+ } catch (const fs::filesystem_error& e) {
+ VERIFY( e.code() == std::errc::file_exists );
+ }
+#endif
+
+ remove_all(dir);
+}
+
int
main()
{
@@ -198,4 +226,5 @@ main()
test03();
test04();
test05();
+ test_pr99290();
}
More information about the Libstdc++-cvs
mailing list