summaryrefslogtreecommitdiff
path: root/libstdc++-v3/src/filesystem/ops.cc
diff options
context:
space:
mode:
authorJonathan Wakely <jwakely@redhat.com>2016-10-24 17:45:31 +0100
committerJonathan Wakely <redi@gcc.gnu.org>2016-10-24 17:45:31 +0100
commitb3dec9e57e6960cae54187b7fa416052c8e32e19 (patch)
tree31de0b552bad0b485a556d5796112652b9f67fa2 /libstdc++-v3/src/filesystem/ops.cc
parent38000825cd37c3f132cd02edc4e8eb79aff4d3a6 (diff)
downloadgcc-b3dec9e57e6960cae54187b7fa416052c8e32e19.tar.gz
Implement DR resolutions for filesystem::copy
* src/filesystem/ops.cc (do_copy_file): Return an error if either source or destination is not a regular file. (copy): Update comment to refer to LWG 2681. Implement 2682 and 2683 resolutions. (read_symlink): Add missing ec.clear(). * testsuite/experimental/filesystem/operations/copy.cc: Update expected behaviour for copying directories with create_symlinks. Verify that error_code arguments are cleared if there's no error. * testsuite/experimental/filesystem/operations/read_symlink.cc: New. From-SVN: r241484
Diffstat (limited to 'libstdc++-v3/src/filesystem/ops.cc')
-rw-r--r--libstdc++-v3/src/filesystem/ops.cc23
1 files changed, 21 insertions, 2 deletions
diff --git a/libstdc++-v3/src/filesystem/ops.cc b/libstdc++-v3/src/filesystem/ops.cc
index 2286e2201f4..6f76053d571 100644
--- a/libstdc++-v3/src/filesystem/ops.cc
+++ b/libstdc++-v3/src/filesystem/ops.cc
@@ -361,6 +361,11 @@ namespace
from_st = &st2;
}
f = make_file_status(*from_st);
+ if (!is_regular_file(f))
+ {
+ ec = std::make_error_code(std::errc::not_supported);
+ return false;
+ }
using opts = fs::copy_options;
@@ -392,6 +397,11 @@ namespace
ec = std::make_error_code(std::errc::file_exists);
return false;
}
+ else if (!is_regular_file(t))
+ {
+ ec = std::make_error_code(std::errc::not_supported);
+ return false;
+ }
}
struct CloseFD {
@@ -489,7 +499,8 @@ fs::copy(const path& from, const path& to, copy_options options,
file_status f, t;
stat_type from_st, to_st;
- // N4099 doesn't check copy_symlinks here, but I think that's a defect.
+ // _GLIBCXX_RESOLVE_LIB_DEFECTS
+ // 2681. filesystem::copy() cannot copy symlinks
if (use_lstat || copy_symlinks
? ::lstat(from.c_str(), &from_st)
: ::stat(from.c_str(), &from_st))
@@ -556,6 +567,10 @@ fs::copy(const path& from, const path& to, copy_options options,
do_copy_file(from, to, options, &from_st, ptr, ec);
}
}
+ // _GLIBCXX_RESOLVE_LIB_DEFECTS
+ // 2682. filesystem::copy() won't create a symlink to a directory
+ else if (is_directory(f) && create_symlinks)
+ ec = std::make_error_code(errc::is_a_directory);
else if (is_directory(f) && (is_set(options, copy_options::recursive)
|| options == copy_options::none))
{
@@ -568,7 +583,10 @@ fs::copy(const path& from, const path& to, copy_options options,
for (const directory_entry& x : directory_iterator(from))
copy(x.path(), to/x.path().filename(), options, ec);
}
- // "Otherwise no effects." (should ec.clear() be called?)
+ // _GLIBCXX_RESOLVE_LIB_DEFECTS
+ // 2683. filesystem::copy() says "no effects"
+ else
+ ec.clear();
}
bool
@@ -1168,6 +1186,7 @@ fs::path fs::read_symlink(const path& p, error_code& ec)
ec.assign(errno, std::generic_category());
return {};
}
+ ec.clear();
return path{buf.data(), buf.data()+len};
#else
ec = std::make_error_code(std::errc::not_supported);