Address LWG 2849 and fix missing failure condition in copy_file.
Previously copy_file didn't handle the case where the input and output were the same file. git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@324187 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -263,18 +263,22 @@ void __copy(const path& from, const path& to, copy_options options,
|
||||
bool __copy_file(const path& from, const path& to, copy_options options,
|
||||
std::error_code *ec)
|
||||
{
|
||||
if (ec) ec->clear();
|
||||
using StatT = struct ::stat;
|
||||
if (ec)
|
||||
ec->clear();
|
||||
|
||||
std::error_code m_ec;
|
||||
auto from_st = detail::posix_stat(from, &m_ec);
|
||||
StatT from_stat;
|
||||
auto from_st = detail::posix_stat(from, from_stat, &m_ec);
|
||||
if (not is_regular_file(from_st)) {
|
||||
if (not m_ec)
|
||||
m_ec = make_error_code(errc::not_supported);
|
||||
set_or_throw(m_ec, ec, "copy_file", from, to);
|
||||
return false;
|
||||
if (not m_ec)
|
||||
m_ec = make_error_code(errc::not_supported);
|
||||
set_or_throw(m_ec, ec, "copy_file", from, to);
|
||||
return false;
|
||||
}
|
||||
|
||||
auto to_st = detail::posix_stat(to, &m_ec);
|
||||
StatT to_stat;
|
||||
auto to_st = detail::posix_stat(to, to_stat, &m_ec);
|
||||
if (!status_known(to_st)) {
|
||||
set_or_throw(m_ec, ec, "copy_file", from, to);
|
||||
return false;
|
||||
@@ -285,6 +289,11 @@ bool __copy_file(const path& from, const path& to, copy_options options,
|
||||
set_or_throw(make_error_code(errc::not_supported), ec, "copy_file", from, to);
|
||||
return false;
|
||||
}
|
||||
if (to_exists && detail::stat_equivalent(from_stat, to_stat)) {
|
||||
set_or_throw(make_error_code(errc::file_exists), ec, "copy_file", from,
|
||||
to);
|
||||
return false;
|
||||
}
|
||||
if (to_exists && bool(copy_options::skip_existing & options)) {
|
||||
return false;
|
||||
}
|
||||
@@ -302,8 +311,9 @@ bool __copy_file(const path& from, const path& to, copy_options options,
|
||||
return detail::copy_file_impl(from, to, from_st.permissions(), ec);
|
||||
}
|
||||
else {
|
||||
set_or_throw(make_error_code(errc::file_exists), ec, "copy", from, to);
|
||||
return false;
|
||||
set_or_throw(make_error_code(errc::file_exists), ec, "copy_file", from,
|
||||
to);
|
||||
return false;
|
||||
}
|
||||
|
||||
_LIBCPP_UNREACHABLE();
|
||||
@@ -443,7 +453,7 @@ bool __equivalent(const path& p1, const path& p2, std::error_code *ec)
|
||||
if (!exists(s2))
|
||||
return make_unsupported_error();
|
||||
if (ec) ec->clear();
|
||||
return (st1.st_dev == st2.st_dev && st1.st_ino == st2.st_ino);
|
||||
return detail::stat_equivalent(st1, st2);
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user