summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--base/file_util.h7
-rw-r--r--base/file_util_posix.cc4
-rw-r--r--base/file_util_win.cc12
-rw-r--r--chrome/common/important_file_writer.cc2
4 files changed, 24 insertions, 1 deletions
diff --git a/base/file_util.h b/base/file_util.h
index a3c9a6e..c51e1a0 100644
--- a/base/file_util.h
+++ b/base/file_util.h
@@ -160,6 +160,13 @@ bool Move(const FilePath& from_path, const FilePath& to_path);
// Deprecated temporary compatibility function.
bool Move(const std::wstring& from_path, const std::wstring& to_path);
+// Renames file |from_path| to |to_path|. Both paths must be on the same
+// volume, or the function will fail. Destination file will be created
+// if it doesn't exist. Prefer this function over Move when dealing with
+// temporary files. On Windows it preserves attributes of the target file.
+// Returns true on success.
+bool ReplaceFile(const FilePath& from_path, const FilePath& to_path);
+
// Copies a single file. Use CopyDirectory to copy directories.
bool CopyFile(const FilePath& from_path, const FilePath& to_path);
// Deprecated temporary compatibility function.
diff --git a/base/file_util_posix.cc b/base/file_util_posix.cc
index 96c1c17..5d44ca3 100644
--- a/base/file_util_posix.cc
+++ b/base/file_util_posix.cc
@@ -168,6 +168,10 @@ bool Move(const FilePath& from_path, const FilePath& to_path) {
return true;
}
+bool ReplaceFile(const FilePath& from_path, const FilePath& to_path) {
+ return (rename(from_path.value().c_str(), to_path.value().c_str()) == 0);
+}
+
bool CopyDirectory(const FilePath& from_path,
const FilePath& to_path,
bool recursive) {
diff --git a/base/file_util_win.cc b/base/file_util_win.cc
index 8964fbf..77247a4 100644
--- a/base/file_util_win.cc
+++ b/base/file_util_win.cc
@@ -116,6 +116,18 @@ bool Move(const FilePath& from_path, const FilePath& to_path) {
return false;
}
+bool ReplaceFile(const FilePath& from_path, const FilePath& to_path) {
+ // Make sure that the target file exists.
+ HANDLE target_file = ::CreateFile(to_path.value().c_str(), 0,
+ FILE_SHARE_READ | FILE_SHARE_WRITE,
+ NULL, CREATE_NEW,
+ FILE_ATTRIBUTE_NORMAL, NULL);
+ if (target_file != INVALID_HANDLE_VALUE)
+ ::CloseHandle(target_file);
+ return ::ReplaceFile(to_path.value().c_str(), from_path.value().c_str(),
+ NULL, 0, NULL, NULL) ? true : false;
+}
+
bool CopyFile(const FilePath& from_path, const FilePath& to_path) {
// NOTE: I suspect we could support longer paths, but that would involve
// analyzing all our usage of files.
diff --git a/chrome/common/important_file_writer.cc b/chrome/common/important_file_writer.cc
index 03e138c..86a7b7d 100644
--- a/chrome/common/important_file_writer.cc
+++ b/chrome/common/important_file_writer.cc
@@ -55,7 +55,7 @@ class WriteToDiskTask : public Task {
return;
}
- if (file_util::Move(tmp_file_path, path_)) {
+ if (file_util::ReplaceFile(tmp_file_path, path_)) {
LogSuccess();
return;
}