summaryrefslogtreecommitdiffstats
path: root/libcxx/src/experimental/filesystem/operations.cpp
diff options
context:
space:
mode:
authorEric Fiselier <eric@efcs.ca>2018-07-22 21:15:15 +0000
committerEric Fiselier <eric@efcs.ca>2018-07-22 21:15:15 +0000
commit37dd491d1353a4106ba5c2425b3e8354401c0ece (patch)
tree349e9f9cf92089438c7528d142ac85778dc2fa8f /libcxx/src/experimental/filesystem/operations.cpp
parent0f3ce8e6404c81801d98f51d97f080c9a0f7a6c1 (diff)
downloadbcm5719-llvm-37dd491d1353a4106ba5c2425b3e8354401c0ece.tar.gz
bcm5719-llvm-37dd491d1353a4106ba5c2425b3e8354401c0ece.zip
Harden copy_file even more.
This patch removes the O_CREAT open flag when we first attempt to open the destination file but we expect it to already exist. This theoretically avoids the possibility that it was removed between when we first stat'ed it, and when we attempt to open it. llvm-svn: 337659
Diffstat (limited to 'libcxx/src/experimental/filesystem/operations.cpp')
-rw-r--r--libcxx/src/experimental/filesystem/operations.cpp12
1 files changed, 7 insertions, 5 deletions
diff --git a/libcxx/src/experimental/filesystem/operations.cpp b/libcxx/src/experimental/filesystem/operations.cpp
index be876ad7787..cc744fb9be3 100644
--- a/libcxx/src/experimental/filesystem/operations.cpp
+++ b/libcxx/src/experimental/filesystem/operations.cpp
@@ -716,7 +716,7 @@ bool __copy_file(const path& from, const path& to, copy_options options,
if (to_exists && skip_existing)
return false;
- auto ShouldCopy = [&]() {
+ bool ShouldCopy = [&]() {
if (to_exists && update_existing) {
auto from_time = detail::extract_mtime(from_stat);
auto to_time = detail::extract_mtime(to_stat_path);
@@ -730,13 +730,15 @@ bool __copy_file(const path& from, const path& to, copy_options options,
if (!to_exists || overwrite_existing)
return true;
return Error(make_error_code(errc::file_exists));
- };
- if (!ShouldCopy())
+ }();
+ if (!ShouldCopy)
return false;
// Don't truncate right away. We may not be opening the file we originally
// looked at; we'll check this later.
- int to_open_flags = O_WRONLY | O_CREAT;
+ int to_open_flags = O_WRONLY;
+ if (!to_exists)
+ to_open_flags |= O_CREAT;
FileDescriptor to_fd = FileDescriptor::create_with_status(
&to, m_ec, to_open_flags, from_stat.st_mode);
if (m_ec)
@@ -745,6 +747,7 @@ bool __copy_file(const path& from, const path& to, copy_options options,
if (to_exists) {
// Check that the file we initially stat'ed is equivalent to the one
// we opened.
+ // FIXME: report this better.
if (!detail::stat_equivalent(to_stat_path, to_fd.get_stat()))
return Error(make_error_code(errc::bad_file_descriptor));
@@ -761,7 +764,6 @@ bool __copy_file(const path& from, const path& to, copy_options options,
}
return true;
-
}
void __copy_symlink(const path& existing_symlink, const path& new_symlink,
OpenPOWER on IntegriCloud