| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "components/filesystem/directory_impl.h" | 5 #include "components/filesystem/directory_impl.h" |
| 6 | 6 |
| 7 #include <utility> | 7 #include <utility> |
| 8 | 8 |
| 9 #include "base/files/file.h" | 9 #include "base/files/file.h" |
| 10 #include "base/files/file_enumerator.h" | 10 #include "base/files/file_enumerator.h" |
| 11 #include "base/files/file_util.h" | 11 #include "base/files/file_util.h" |
| 12 #include "base/files/scoped_temp_dir.h" | 12 #include "base/files/scoped_temp_dir.h" |
| 13 #include "base/logging.h" | 13 #include "base/logging.h" |
| 14 #include "build/build_config.h" | 14 #include "build/build_config.h" |
| 15 #include "components/filesystem/file_impl.h" | 15 #include "components/filesystem/file_impl.h" |
| 16 #include "components/filesystem/lock_table.h" | 16 #include "components/filesystem/lock_table.h" |
| 17 #include "components/filesystem/util.h" | 17 #include "components/filesystem/util.h" |
| 18 #include "mojo/common/common_type_converters.h" | 18 #include "mojo/common/common_type_converters.h" |
| 19 #include "mojo/public/cpp/bindings/strong_binding.h" |
| 19 #include "mojo/public/cpp/system/platform_handle.h" | 20 #include "mojo/public/cpp/system/platform_handle.h" |
| 20 | 21 |
| 21 namespace filesystem { | 22 namespace filesystem { |
| 22 | 23 |
| 23 DirectoryImpl::DirectoryImpl(mojo::InterfaceRequest<mojom::Directory> request, | 24 DirectoryImpl::DirectoryImpl(base::FilePath directory_path, |
| 24 base::FilePath directory_path, | |
| 25 scoped_refptr<SharedTempDir> temp_dir, | 25 scoped_refptr<SharedTempDir> temp_dir, |
| 26 scoped_refptr<LockTable> lock_table) | 26 scoped_refptr<LockTable> lock_table) |
| 27 : binding_(this, std::move(request)), | 27 : directory_path_(directory_path), |
| 28 directory_path_(directory_path), | |
| 29 temp_dir_(std::move(temp_dir)), | 28 temp_dir_(std::move(temp_dir)), |
| 30 lock_table_(std::move(lock_table)) {} | 29 lock_table_(std::move(lock_table)) {} |
| 31 | 30 |
| 32 DirectoryImpl::~DirectoryImpl() {} | 31 DirectoryImpl::~DirectoryImpl() {} |
| 33 | 32 |
| 34 void DirectoryImpl::Read(const ReadCallback& callback) { | 33 void DirectoryImpl::Read(const ReadCallback& callback) { |
| 35 mojo::Array<mojom::DirectoryEntryPtr> entries; | 34 mojo::Array<mojom::DirectoryEntryPtr> entries; |
| 36 base::FileEnumerator directory_enumerator( | 35 base::FileEnumerator directory_enumerator( |
| 37 directory_path_, false, | 36 directory_path_, false, |
| 38 base::FileEnumerator::DIRECTORIES | base::FileEnumerator::FILES); | 37 base::FileEnumerator::DIRECTORIES | base::FileEnumerator::FILES); |
| 39 for (base::FilePath name = directory_enumerator.Next(); !name.empty(); | 38 for (base::FilePath name = directory_enumerator.Next(); !name.empty(); |
| 40 name = directory_enumerator.Next()) { | 39 name = directory_enumerator.Next()) { |
| 41 base::FileEnumerator::FileInfo info = directory_enumerator.GetInfo(); | 40 base::FileEnumerator::FileInfo info = directory_enumerator.GetInfo(); |
| 42 mojom::DirectoryEntryPtr entry = mojom::DirectoryEntry::New(); | 41 mojom::DirectoryEntryPtr entry = mojom::DirectoryEntry::New(); |
| 43 entry->type = info.IsDirectory() ? mojom::FsFileType::DIRECTORY | 42 entry->type = info.IsDirectory() ? mojom::FsFileType::DIRECTORY |
| 44 : mojom::FsFileType::REGULAR_FILE; | 43 : mojom::FsFileType::REGULAR_FILE; |
| 45 entry->name = info.GetName().AsUTF8Unsafe(); | 44 entry->name = info.GetName().AsUTF8Unsafe(); |
| 46 entries.push_back(std::move(entry)); | 45 entries.push_back(std::move(entry)); |
| 47 } | 46 } |
| 48 | 47 |
| 49 callback.Run(mojom::FileError::OK, std::move(entries)); | 48 callback.Run(mojom::FileError::OK, std::move(entries)); |
| 50 } | 49 } |
| 51 | 50 |
| 52 // TODO(erg): Consider adding an implementation of Stat()/Touch() to the | 51 // TODO(erg): Consider adding an implementation of Stat()/Touch() to the |
| 53 // directory, too. Right now, the base::File abstractions do not really deal | 52 // directory, too. Right now, the base::File abstractions do not really deal |
| 54 // with directories properly, so these are broken for now. | 53 // with directories properly, so these are broken for now. |
| 55 | 54 |
| 56 // TODO(vtl): Move the implementation to a thread pool. | 55 // TODO(vtl): Move the implementation to a thread pool. |
| 57 void DirectoryImpl::OpenFile(const mojo::String& raw_path, | 56 void DirectoryImpl::OpenFile(const mojo::String& raw_path, |
| 58 mojo::InterfaceRequest<mojom::File> file, | 57 mojom::FileRequest file, |
| 59 uint32_t open_flags, | 58 uint32_t open_flags, |
| 60 const OpenFileCallback& callback) { | 59 const OpenFileCallback& callback) { |
| 61 base::FilePath path; | 60 base::FilePath path; |
| 62 mojom::FileError error = ValidatePath(raw_path, directory_path_, &path); | 61 mojom::FileError error = ValidatePath(raw_path, directory_path_, &path); |
| 63 if (error != mojom::FileError::OK) { | 62 if (error != mojom::FileError::OK) { |
| 64 callback.Run(error); | 63 callback.Run(error); |
| 65 return; | 64 return; |
| 66 } | 65 } |
| 67 | 66 |
| 68 if (base::DirectoryExists(path)) { | 67 if (base::DirectoryExists(path)) { |
| 69 // We must not return directories as files. In the file abstraction, we can | 68 // We must not return directories as files. In the file abstraction, we can |
| 70 // fetch raw file descriptors over mojo pipes, and passing a file | 69 // fetch raw file descriptors over mojo pipes, and passing a file |
| 71 // descriptor to a directory is a sandbox escape on Windows. | 70 // descriptor to a directory is a sandbox escape on Windows. |
| 72 callback.Run(mojom::FileError::NOT_A_FILE); | 71 callback.Run(mojom::FileError::NOT_A_FILE); |
| 73 return; | 72 return; |
| 74 } | 73 } |
| 75 | 74 |
| 76 base::File base_file(path, open_flags); | 75 base::File base_file(path, open_flags); |
| 77 if (!base_file.IsValid()) { | 76 if (!base_file.IsValid()) { |
| 78 callback.Run(GetError(base_file)); | 77 callback.Run(GetError(base_file)); |
| 79 return; | 78 return; |
| 80 } | 79 } |
| 81 | 80 |
| 82 if (file.is_pending()) { | 81 if (file.is_pending()) { |
| 83 new FileImpl(std::move(file), path, std::move(base_file), temp_dir_, | 82 mojo::MakeStrongBinding( |
| 84 lock_table_); | 83 base::MakeUnique<FileImpl>(path, std::move(base_file), temp_dir_, |
| 84 lock_table_), |
| 85 std::move(file)); |
| 85 } | 86 } |
| 86 callback.Run(mojom::FileError::OK); | 87 callback.Run(mojom::FileError::OK); |
| 87 } | 88 } |
| 88 | 89 |
| 89 void DirectoryImpl::OpenFileHandle(const mojo::String& raw_path, | 90 void DirectoryImpl::OpenFileHandle(const mojo::String& raw_path, |
| 90 uint32_t open_flags, | 91 uint32_t open_flags, |
| 91 const OpenFileHandleCallback& callback) { | 92 const OpenFileHandleCallback& callback) { |
| 92 mojom::FileError error = mojom::FileError::OK; | 93 mojom::FileError error = mojom::FileError::OK; |
| 93 mojo::ScopedHandle handle = OpenFileHandleImpl(raw_path, open_flags, &error); | 94 mojo::ScopedHandle handle = OpenFileHandleImpl(raw_path, open_flags, &error); |
| 94 callback.Run(error, std::move(handle)); | 95 callback.Run(error, std::move(handle)); |
| 95 } | 96 } |
| 96 | 97 |
| 97 void DirectoryImpl::OpenFileHandles( | 98 void DirectoryImpl::OpenFileHandles( |
| 98 mojo::Array<mojom::FileOpenDetailsPtr> details, | 99 mojo::Array<mojom::FileOpenDetailsPtr> details, |
| 99 const OpenFileHandlesCallback& callback) { | 100 const OpenFileHandlesCallback& callback) { |
| 100 mojo::Array<mojom::FileOpenResultPtr> results( | 101 mojo::Array<mojom::FileOpenResultPtr> results( |
| 101 mojo::Array<mojom::FileOpenResultPtr>::New(details.size())); | 102 mojo::Array<mojom::FileOpenResultPtr>::New(details.size())); |
| 102 size_t i = 0; | 103 size_t i = 0; |
| 103 for (const auto& detail : details) { | 104 for (const auto& detail : details) { |
| 104 mojom::FileOpenResultPtr result(mojom::FileOpenResult::New()); | 105 mojom::FileOpenResultPtr result(mojom::FileOpenResult::New()); |
| 105 result->path = detail->path; | 106 result->path = detail->path; |
| 106 result->file_handle = | 107 result->file_handle = |
| 107 OpenFileHandleImpl(detail->path, detail->open_flags, &result->error); | 108 OpenFileHandleImpl(detail->path, detail->open_flags, &result->error); |
| 108 results[i++] = std::move(result); | 109 results[i++] = std::move(result); |
| 109 } | 110 } |
| 110 callback.Run(std::move(results)); | 111 callback.Run(std::move(results)); |
| 111 } | 112 } |
| 112 | 113 |
| 113 void DirectoryImpl::OpenDirectory( | 114 void DirectoryImpl::OpenDirectory(const mojo::String& raw_path, |
| 114 const mojo::String& raw_path, | 115 mojom::DirectoryRequest directory, |
| 115 mojo::InterfaceRequest<mojom::Directory> directory, | 116 uint32_t open_flags, |
| 116 uint32_t open_flags, | 117 const OpenDirectoryCallback& callback) { |
| 117 const OpenDirectoryCallback& callback) { | |
| 118 base::FilePath path; | 118 base::FilePath path; |
| 119 mojom::FileError error = ValidatePath(raw_path, directory_path_, &path); | 119 mojom::FileError error = ValidatePath(raw_path, directory_path_, &path); |
| 120 if (error != mojom::FileError::OK) { | 120 if (error != mojom::FileError::OK) { |
| 121 callback.Run(error); | 121 callback.Run(error); |
| 122 return; | 122 return; |
| 123 } | 123 } |
| 124 | 124 |
| 125 if (!base::DirectoryExists(path)) { | 125 if (!base::DirectoryExists(path)) { |
| 126 if (base::PathExists(path)) { | 126 if (base::PathExists(path)) { |
| 127 callback.Run(mojom::FileError::NOT_A_DIRECTORY); | 127 callback.Run(mojom::FileError::NOT_A_DIRECTORY); |
| 128 return; | 128 return; |
| 129 } | 129 } |
| 130 | 130 |
| 131 if (!(open_flags & mojom::kFlagOpenAlways || | 131 if (!(open_flags & mojom::kFlagOpenAlways || |
| 132 open_flags & mojom::kFlagCreate)) { | 132 open_flags & mojom::kFlagCreate)) { |
| 133 // The directory doesn't exist, and we weren't passed parameters to | 133 // The directory doesn't exist, and we weren't passed parameters to |
| 134 // create it. | 134 // create it. |
| 135 callback.Run(mojom::FileError::NOT_FOUND); | 135 callback.Run(mojom::FileError::NOT_FOUND); |
| 136 return; | 136 return; |
| 137 } | 137 } |
| 138 | 138 |
| 139 base::File::Error error; | 139 base::File::Error error; |
| 140 if (!base::CreateDirectoryAndGetError(path, &error)) { | 140 if (!base::CreateDirectoryAndGetError(path, &error)) { |
| 141 callback.Run(static_cast<filesystem::mojom::FileError>(error)); | 141 callback.Run(static_cast<filesystem::mojom::FileError>(error)); |
| 142 return; | 142 return; |
| 143 } | 143 } |
| 144 } | 144 } |
| 145 | 145 |
| 146 if (directory.is_pending()) | 146 if (directory.is_pending()) { |
| 147 new DirectoryImpl(std::move(directory), path, temp_dir_, lock_table_); | 147 mojo::MakeStrongBinding( |
| 148 base::MakeUnique<DirectoryImpl>(path, temp_dir_, lock_table_), |
| 149 std::move(directory)); |
| 150 } |
| 151 |
| 148 callback.Run(mojom::FileError::OK); | 152 callback.Run(mojom::FileError::OK); |
| 149 } | 153 } |
| 150 | 154 |
| 151 void DirectoryImpl::Rename(const mojo::String& raw_old_path, | 155 void DirectoryImpl::Rename(const mojo::String& raw_old_path, |
| 152 const mojo::String& raw_new_path, | 156 const mojo::String& raw_new_path, |
| 153 const RenameCallback& callback) { | 157 const RenameCallback& callback) { |
| 154 base::FilePath old_path; | 158 base::FilePath old_path; |
| 155 mojom::FileError error = | 159 mojom::FileError error = |
| 156 ValidatePath(raw_old_path, directory_path_, &old_path); | 160 ValidatePath(raw_old_path, directory_path_, &old_path); |
| 157 if (error != mojom::FileError::OK) { | 161 if (error != mojom::FileError::OK) { |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 250 | 254 |
| 251 base::File::Info info; | 255 base::File::Info info; |
| 252 if (!base_file.GetInfo(&info)) { | 256 if (!base_file.GetInfo(&info)) { |
| 253 callback.Run(mojom::FileError::FAILED, nullptr); | 257 callback.Run(mojom::FileError::FAILED, nullptr); |
| 254 return; | 258 return; |
| 255 } | 259 } |
| 256 | 260 |
| 257 callback.Run(mojom::FileError::OK, MakeFileInformation(info)); | 261 callback.Run(mojom::FileError::OK, MakeFileInformation(info)); |
| 258 } | 262 } |
| 259 | 263 |
| 260 void DirectoryImpl::Clone(mojo::InterfaceRequest<mojom::Directory> directory) { | 264 void DirectoryImpl::Clone(mojom::DirectoryRequest directory) { |
| 261 if (directory.is_pending()) { | 265 if (directory.is_pending()) { |
| 262 new DirectoryImpl(std::move(directory), directory_path_, | 266 mojo::MakeStrongBinding(base::MakeUnique<DirectoryImpl>( |
| 263 temp_dir_, lock_table_); | 267 directory_path_, temp_dir_, lock_table_), |
| 268 std::move(directory)); |
| 264 } | 269 } |
| 265 } | 270 } |
| 266 | 271 |
| 267 void DirectoryImpl::ReadEntireFile(const mojo::String& raw_path, | 272 void DirectoryImpl::ReadEntireFile(const mojo::String& raw_path, |
| 268 const ReadEntireFileCallback& callback) { | 273 const ReadEntireFileCallback& callback) { |
| 269 base::FilePath path; | 274 base::FilePath path; |
| 270 mojom::FileError error = ValidatePath(raw_path, directory_path_, &path); | 275 mojom::FileError error = ValidatePath(raw_path, directory_path_, &path); |
| 271 if (error != mojom::FileError::OK) { | 276 if (error != mojom::FileError::OK) { |
| 272 callback.Run(error, mojo::Array<uint8_t>()); | 277 callback.Run(error, mojo::Array<uint8_t>()); |
| 273 return; | 278 return; |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 350 if (!base_file.IsValid()) { | 355 if (!base_file.IsValid()) { |
| 351 *error = GetError(base_file); | 356 *error = GetError(base_file); |
| 352 return mojo::ScopedHandle(); | 357 return mojo::ScopedHandle(); |
| 353 } | 358 } |
| 354 | 359 |
| 355 *error = mojom::FileError::OK; | 360 *error = mojom::FileError::OK; |
| 356 return mojo::WrapPlatformFile(base_file.TakePlatformFile()); | 361 return mojo::WrapPlatformFile(base_file.TakePlatformFile()); |
| 357 } | 362 } |
| 358 | 363 |
| 359 } // namespace filesystem | 364 } // namespace filesystem |
| OLD | NEW |