summaryrefslogtreecommitdiff
path: root/chromium/webkit/browser/fileapi/native_file_util.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/webkit/browser/fileapi/native_file_util.cc')
-rw-r--r--chromium/webkit/browser/fileapi/native_file_util.cc95
1 files changed, 80 insertions, 15 deletions
diff --git a/chromium/webkit/browser/fileapi/native_file_util.cc b/chromium/webkit/browser/fileapi/native_file_util.cc
index 32e9467091c..9754d6c64a8 100644
--- a/chromium/webkit/browser/fileapi/native_file_util.cc
+++ b/chromium/webkit/browser/fileapi/native_file_util.cc
@@ -7,7 +7,9 @@
#include "base/file_util.h"
#include "base/files/file_enumerator.h"
#include "base/memory/scoped_ptr.h"
+#include "net/base/file_stream.h"
#include "webkit/browser/fileapi/file_system_operation_context.h"
+#include "webkit/browser/fileapi/file_system_url.h"
namespace fileapi {
@@ -32,6 +34,42 @@ bool SetPlatformSpecificDirectoryPermissions(const base::FilePath& dir_path) {
return true;
}
+// Copies a file |from| to |to|, and ensure the written content is synced to
+// the disk. This is essentially base::CopyFile followed by fsync().
+bool CopyFileAndSync(const base::FilePath& from, const base::FilePath& to) {
+ net::FileStream infile(NULL);
+ if (infile.OpenSync(from,
+ base::PLATFORM_FILE_OPEN | base:: PLATFORM_FILE_READ) < 0) {
+ return false;
+ }
+
+ net::FileStream outfile(NULL);
+ if (outfile.OpenSync(to,
+ base::PLATFORM_FILE_CREATE_ALWAYS | base:: PLATFORM_FILE_WRITE) < 0) {
+ return false;
+ }
+
+ const int kBufferSize = 32768;
+ std::vector<char> buffer(kBufferSize);
+
+ for (;;) {
+ int bytes_read = infile.ReadSync(&buffer[0], kBufferSize);
+ if (bytes_read < 0)
+ return false;
+ if (bytes_read == 0)
+ break;
+ for (int bytes_written = 0; bytes_written < bytes_read; ) {
+ int bytes_written_partial = outfile.WriteSync(&buffer[bytes_written],
+ bytes_read - bytes_written);
+ if (bytes_written_partial < 0)
+ return false;
+ bytes_written += bytes_written_partial;
+ }
+ }
+
+ return outfile.FlushSync() >= 0;
+}
+
} // namespace
using base::PlatformFile;
@@ -76,6 +114,15 @@ bool NativeFileEnumerator::IsDirectory() {
return file_util_info_.IsDirectory();
}
+NativeFileUtil::CopyOrMoveMode NativeFileUtil::CopyOrMoveModeForDestination(
+ const FileSystemURL& dest_url, bool copy) {
+ if (copy) {
+ return dest_url.mount_option().copy_sync_option() == COPY_SYNC_OPTION_SYNC ?
+ COPY_SYNC : COPY_NOSYNC;
+ }
+ return MOVE;
+}
+
PlatformFileError NativeFileUtil::CreateOrOpen(
const base::FilePath& path, int file_flags,
PlatformFile* file_handle, bool* created) {
@@ -137,11 +184,15 @@ PlatformFileError NativeFileUtil::CreateDirectory(
if (path_exists && !base::DirectoryExists(path))
return base::PLATFORM_FILE_ERROR_EXISTS;
- if (!file_util::CreateDirectory(path))
+ if (!base::CreateDirectory(path))
return base::PLATFORM_FILE_ERROR_FAILED;
- if (!SetPlatformSpecificDirectoryPermissions(path))
- return base::PLATFORM_FILE_ERROR_FAILED;
+ if (!SetPlatformSpecificDirectoryPermissions(path)) {
+ // Since some file systems don't support permission setting, we do not treat
+ // an error from the function as the failure of copying. Just log it.
+ LOG(WARNING) << "Setting directory permission failed: "
+ << path.AsUTF8Unsafe();
+ }
return base::PLATFORM_FILE_OK;
}
@@ -151,7 +202,7 @@ PlatformFileError NativeFileUtil::GetFileInfo(
base::PlatformFileInfo* file_info) {
if (!base::PathExists(path))
return base::PLATFORM_FILE_ERROR_NOT_FOUND;
- if (!file_util::GetFileInfo(path, file_info))
+ if (!base::GetFileInfo(path, file_info))
return base::PLATFORM_FILE_ERROR_FAILED;
return base::PLATFORM_FILE_OK;
}
@@ -169,8 +220,7 @@ PlatformFileError NativeFileUtil::Touch(
const base::FilePath& path,
const base::Time& last_access_time,
const base::Time& last_modified_time) {
- if (!file_util::TouchFile(
- path, last_access_time, last_modified_time))
+ if (!base::TouchFile(path, last_access_time, last_modified_time))
return base::PLATFORM_FILE_ERROR_FAILED;
return base::PLATFORM_FILE_OK;
}
@@ -205,13 +255,15 @@ bool NativeFileUtil::DirectoryExists(const base::FilePath& path) {
PlatformFileError NativeFileUtil::CopyOrMoveFile(
const base::FilePath& src_path,
const base::FilePath& dest_path,
- bool copy) {
+ FileSystemOperation::CopyOrMoveOption option,
+ CopyOrMoveMode mode) {
base::PlatformFileInfo info;
base::PlatformFileError error = NativeFileUtil::GetFileInfo(src_path, &info);
if (error != base::PLATFORM_FILE_OK)
return error;
if (info.is_directory)
return base::PLATFORM_FILE_ERROR_NOT_A_FILE;
+ base::Time last_modified = info.last_modified;
error = NativeFileUtil::GetFileInfo(dest_path, &info);
if (error != base::PLATFORM_FILE_OK &&
@@ -227,14 +279,27 @@ PlatformFileError NativeFileUtil::CopyOrMoveFile(
return base::PLATFORM_FILE_ERROR_NOT_FOUND;
}
- if (copy) {
- if (base::CopyFile(src_path, dest_path))
- return base::PLATFORM_FILE_OK;
- } else {
- if (base::Move(src_path, dest_path))
- return base::PLATFORM_FILE_OK;
+ switch (mode) {
+ case COPY_NOSYNC:
+ if (!base::CopyFile(src_path, dest_path))
+ return base::PLATFORM_FILE_ERROR_FAILED;
+ break;
+ case COPY_SYNC:
+ if (!CopyFileAndSync(src_path, dest_path))
+ return base::PLATFORM_FILE_ERROR_FAILED;
+ break;
+ case MOVE:
+ if (!base::Move(src_path, dest_path))
+ return base::PLATFORM_FILE_ERROR_FAILED;
+ break;
}
- return base::PLATFORM_FILE_ERROR_FAILED;
+
+ // Preserve the last modified time. Do not return error here even if
+ // the setting is failed, because the copy itself is successfully done.
+ if (option == FileSystemOperation::OPTION_PRESERVE_LAST_MODIFIED)
+ base::TouchFile(dest_path, last_modified, last_modified);
+
+ return base::PLATFORM_FILE_OK;
}
PlatformFileError NativeFileUtil::DeleteFile(const base::FilePath& path) {
@@ -252,7 +317,7 @@ PlatformFileError NativeFileUtil::DeleteDirectory(const base::FilePath& path) {
return base::PLATFORM_FILE_ERROR_NOT_FOUND;
if (!base::DirectoryExists(path))
return base::PLATFORM_FILE_ERROR_NOT_A_DIRECTORY;
- if (!file_util::IsDirectoryEmpty(path))
+ if (!base::IsDirectoryEmpty(path))
return base::PLATFORM_FILE_ERROR_NOT_EMPTY;
if (!base::DeleteFile(path, false))
return base::PLATFORM_FILE_ERROR_FAILED;