| 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/platform_handle/platform_handle_functions.h" | 19 #include "mojo/platform_handle/platform_handle_functions.h" |
| 20 | 20 |
| 21 namespace filesystem { | 21 namespace filesystem { |
| 22 | 22 |
| 23 DirectoryImpl::DirectoryImpl(mojo::InterfaceRequest<Directory> request, | 23 DirectoryImpl::DirectoryImpl(mojo::InterfaceRequest<mojom::Directory> request, |
| 24 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 : binding_(this, std::move(request)), |
| 28 directory_path_(directory_path), | 28 directory_path_(directory_path), |
| 29 temp_dir_(std::move(temp_dir)), | 29 temp_dir_(std::move(temp_dir)), |
| 30 lock_table_(std::move(lock_table)) {} | 30 lock_table_(std::move(lock_table)) {} |
| 31 | 31 |
| 32 DirectoryImpl::~DirectoryImpl() {} | 32 DirectoryImpl::~DirectoryImpl() {} |
| 33 | 33 |
| 34 void DirectoryImpl::Read(const ReadCallback& callback) { | 34 void DirectoryImpl::Read(const ReadCallback& callback) { |
| 35 mojo::Array<DirectoryEntryPtr> entries; | 35 mojo::Array<mojom::DirectoryEntryPtr> entries; |
| 36 base::FileEnumerator directory_enumerator( | 36 base::FileEnumerator directory_enumerator( |
| 37 directory_path_, false, | 37 directory_path_, false, |
| 38 base::FileEnumerator::DIRECTORIES | base::FileEnumerator::FILES); | 38 base::FileEnumerator::DIRECTORIES | base::FileEnumerator::FILES); |
| 39 for (base::FilePath name = directory_enumerator.Next(); !name.empty(); | 39 for (base::FilePath name = directory_enumerator.Next(); !name.empty(); |
| 40 name = directory_enumerator.Next()) { | 40 name = directory_enumerator.Next()) { |
| 41 base::FileEnumerator::FileInfo info = directory_enumerator.GetInfo(); | 41 base::FileEnumerator::FileInfo info = directory_enumerator.GetInfo(); |
| 42 DirectoryEntryPtr entry = DirectoryEntry::New(); | 42 mojom::DirectoryEntryPtr entry = mojom::DirectoryEntry::New(); |
| 43 entry->type = | 43 entry->type = info.IsDirectory() ? mojom::FsFileType::DIRECTORY |
| 44 info.IsDirectory() ? FsFileType::DIRECTORY : FsFileType::REGULAR_FILE; | 44 : mojom::FsFileType::REGULAR_FILE; |
| 45 entry->name = info.GetName().AsUTF8Unsafe(); | 45 entry->name = info.GetName().AsUTF8Unsafe(); |
| 46 entries.push_back(std::move(entry)); | 46 entries.push_back(std::move(entry)); |
| 47 } | 47 } |
| 48 | 48 |
| 49 callback.Run(FileError::OK, std::move(entries)); | 49 callback.Run(mojom::FileError::OK, std::move(entries)); |
| 50 } | 50 } |
| 51 | 51 |
| 52 // TODO(erg): Consider adding an implementation of Stat()/Touch() to the | 52 // TODO(erg): Consider adding an implementation of Stat()/Touch() to the |
| 53 // directory, too. Right now, the base::File abstractions do not really deal | 53 // directory, too. Right now, the base::File abstractions do not really deal |
| 54 // with directories properly, so these are broken for now. | 54 // with directories properly, so these are broken for now. |
| 55 | 55 |
| 56 // TODO(vtl): Move the implementation to a thread pool. | 56 // TODO(vtl): Move the implementation to a thread pool. |
| 57 void DirectoryImpl::OpenFile(const mojo::String& raw_path, | 57 void DirectoryImpl::OpenFile(const mojo::String& raw_path, |
| 58 mojo::InterfaceRequest<File> file, | 58 mojo::InterfaceRequest<mojom::File> file, |
| 59 uint32_t open_flags, | 59 uint32_t open_flags, |
| 60 const OpenFileCallback& callback) { | 60 const OpenFileCallback& callback) { |
| 61 base::FilePath path; | 61 base::FilePath path; |
| 62 FileError error = ValidatePath(raw_path, directory_path_, &path); | 62 mojom::FileError error = ValidatePath(raw_path, directory_path_, &path); |
| 63 if (error != FileError::OK) { | 63 if (error != mojom::FileError::OK) { |
| 64 callback.Run(error); | 64 callback.Run(error); |
| 65 return; | 65 return; |
| 66 } | 66 } |
| 67 | 67 |
| 68 if (base::DirectoryExists(path)) { | 68 if (base::DirectoryExists(path)) { |
| 69 // We must not return directories as files. In the file abstraction, we can | 69 // 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 | 70 // fetch raw file descriptors over mojo pipes, and passing a file |
| 71 // descriptor to a directory is a sandbox escape on Windows. | 71 // descriptor to a directory is a sandbox escape on Windows. |
| 72 callback.Run(FileError::NOT_A_FILE); | 72 callback.Run(mojom::FileError::NOT_A_FILE); |
| 73 return; | 73 return; |
| 74 } | 74 } |
| 75 | 75 |
| 76 base::File base_file(path, open_flags); | 76 base::File base_file(path, open_flags); |
| 77 if (!base_file.IsValid()) { | 77 if (!base_file.IsValid()) { |
| 78 callback.Run(GetError(base_file)); | 78 callback.Run(GetError(base_file)); |
| 79 return; | 79 return; |
| 80 } | 80 } |
| 81 | 81 |
| 82 if (file.is_pending()) { | 82 if (file.is_pending()) { |
| 83 new FileImpl(std::move(file), path, std::move(base_file), temp_dir_, | 83 new FileImpl(std::move(file), path, std::move(base_file), temp_dir_, |
| 84 lock_table_); | 84 lock_table_); |
| 85 } | 85 } |
| 86 callback.Run(FileError::OK); | 86 callback.Run(mojom::FileError::OK); |
| 87 } | 87 } |
| 88 | 88 |
| 89 void DirectoryImpl::OpenFileHandle(const mojo::String& raw_path, | 89 void DirectoryImpl::OpenFileHandle(const mojo::String& raw_path, |
| 90 uint32_t open_flags, | 90 uint32_t open_flags, |
| 91 const OpenFileHandleCallback& callback) { | 91 const OpenFileHandleCallback& callback) { |
| 92 FileError error = FileError::OK; | 92 mojom::FileError error = mojom::FileError::OK; |
| 93 mojo::ScopedHandle handle = OpenFileHandleImpl(raw_path, open_flags, &error); | 93 mojo::ScopedHandle handle = OpenFileHandleImpl(raw_path, open_flags, &error); |
| 94 callback.Run(error, std::move(handle)); | 94 callback.Run(error, std::move(handle)); |
| 95 } | 95 } |
| 96 | 96 |
| 97 void DirectoryImpl::OpenFileHandles(mojo::Array<FileOpenDetailsPtr> details, | 97 void DirectoryImpl::OpenFileHandles( |
| 98 const OpenFileHandlesCallback& callback) { | 98 mojo::Array<mojom::FileOpenDetailsPtr> details, |
| 99 mojo::Array<FileOpenResultPtr> results( | 99 const OpenFileHandlesCallback& callback) { |
| 100 mojo::Array<FileOpenResultPtr>::New(details.size())); | 100 mojo::Array<mojom::FileOpenResultPtr> results( |
| 101 mojo::Array<mojom::FileOpenResultPtr>::New(details.size())); |
| 101 size_t i = 0; | 102 size_t i = 0; |
| 102 for (const auto& detail : details) { | 103 for (const auto& detail : details) { |
| 103 FileOpenResultPtr result(FileOpenResult::New()); | 104 mojom::FileOpenResultPtr result(mojom::FileOpenResult::New()); |
| 104 result->path = detail->path; | 105 result->path = detail->path; |
| 105 result->file_handle = | 106 result->file_handle = |
| 106 OpenFileHandleImpl(detail->path, detail->open_flags, &result->error); | 107 OpenFileHandleImpl(detail->path, detail->open_flags, &result->error); |
| 107 results[i++] = std::move(result); | 108 results[i++] = std::move(result); |
| 108 } | 109 } |
| 109 callback.Run(std::move(results)); | 110 callback.Run(std::move(results)); |
| 110 } | 111 } |
| 111 | 112 |
| 112 void DirectoryImpl::OpenDirectory(const mojo::String& raw_path, | 113 void DirectoryImpl::OpenDirectory( |
| 113 mojo::InterfaceRequest<Directory> directory, | 114 const mojo::String& raw_path, |
| 114 uint32_t open_flags, | 115 mojo::InterfaceRequest<mojom::Directory> directory, |
| 115 const OpenDirectoryCallback& callback) { | 116 uint32_t open_flags, |
| 117 const OpenDirectoryCallback& callback) { |
| 116 base::FilePath path; | 118 base::FilePath path; |
| 117 FileError error = ValidatePath(raw_path, directory_path_, &path); | 119 mojom::FileError error = ValidatePath(raw_path, directory_path_, &path); |
| 118 if (error != FileError::OK) { | 120 if (error != mojom::FileError::OK) { |
| 119 callback.Run(error); | 121 callback.Run(error); |
| 120 return; | 122 return; |
| 121 } | 123 } |
| 122 | 124 |
| 123 if (!base::DirectoryExists(path)) { | 125 if (!base::DirectoryExists(path)) { |
| 124 if (base::PathExists(path)) { | 126 if (base::PathExists(path)) { |
| 125 callback.Run(FileError::NOT_A_DIRECTORY); | 127 callback.Run(mojom::FileError::NOT_A_DIRECTORY); |
| 126 return; | 128 return; |
| 127 } | 129 } |
| 128 | 130 |
| 129 if (!(open_flags & kFlagOpenAlways || open_flags & kFlagCreate)) { | 131 if (!(open_flags & mojom::kFlagOpenAlways || |
| 132 open_flags & mojom::kFlagCreate)) { |
| 130 // 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 |
| 131 // create it. | 134 // create it. |
| 132 callback.Run(FileError::NOT_FOUND); | 135 callback.Run(mojom::FileError::NOT_FOUND); |
| 133 return; | 136 return; |
| 134 } | 137 } |
| 135 | 138 |
| 136 base::File::Error error; | 139 base::File::Error error; |
| 137 if (!base::CreateDirectoryAndGetError(path, &error)) { | 140 if (!base::CreateDirectoryAndGetError(path, &error)) { |
| 138 callback.Run(static_cast<filesystem::FileError>(error)); | 141 callback.Run(static_cast<filesystem::mojom::FileError>(error)); |
| 139 return; | 142 return; |
| 140 } | 143 } |
| 141 } | 144 } |
| 142 | 145 |
| 143 if (directory.is_pending()) | 146 if (directory.is_pending()) |
| 144 new DirectoryImpl(std::move(directory), path, temp_dir_, lock_table_); | 147 new DirectoryImpl(std::move(directory), path, temp_dir_, lock_table_); |
| 145 callback.Run(FileError::OK); | 148 callback.Run(mojom::FileError::OK); |
| 146 } | 149 } |
| 147 | 150 |
| 148 void DirectoryImpl::Rename(const mojo::String& raw_old_path, | 151 void DirectoryImpl::Rename(const mojo::String& raw_old_path, |
| 149 const mojo::String& raw_new_path, | 152 const mojo::String& raw_new_path, |
| 150 const RenameCallback& callback) { | 153 const RenameCallback& callback) { |
| 151 base::FilePath old_path; | 154 base::FilePath old_path; |
| 152 FileError error = ValidatePath(raw_old_path, directory_path_, &old_path); | 155 mojom::FileError error = |
| 153 if (error != FileError::OK) { | 156 ValidatePath(raw_old_path, directory_path_, &old_path); |
| 157 if (error != mojom::FileError::OK) { |
| 154 callback.Run(error); | 158 callback.Run(error); |
| 155 return; | 159 return; |
| 156 } | 160 } |
| 157 | 161 |
| 158 base::FilePath new_path; | 162 base::FilePath new_path; |
| 159 error = ValidatePath(raw_new_path, directory_path_, &new_path); | 163 error = ValidatePath(raw_new_path, directory_path_, &new_path); |
| 160 if (error != FileError::OK) { | 164 if (error != mojom::FileError::OK) { |
| 161 callback.Run(error); | 165 callback.Run(error); |
| 162 return; | 166 return; |
| 163 } | 167 } |
| 164 | 168 |
| 165 if (!base::Move(old_path, new_path)) { | 169 if (!base::Move(old_path, new_path)) { |
| 166 callback.Run(FileError::FAILED); | 170 callback.Run(mojom::FileError::FAILED); |
| 167 return; | 171 return; |
| 168 } | 172 } |
| 169 | 173 |
| 170 callback.Run(FileError::OK); | 174 callback.Run(mojom::FileError::OK); |
| 171 } | 175 } |
| 172 | 176 |
| 173 void DirectoryImpl::Delete(const mojo::String& raw_path, | 177 void DirectoryImpl::Delete(const mojo::String& raw_path, |
| 174 uint32_t delete_flags, | 178 uint32_t delete_flags, |
| 175 const DeleteCallback& callback) { | 179 const DeleteCallback& callback) { |
| 176 base::FilePath path; | 180 base::FilePath path; |
| 177 FileError error = ValidatePath(raw_path, directory_path_, &path); | 181 mojom::FileError error = ValidatePath(raw_path, directory_path_, &path); |
| 178 if (error != FileError::OK) { | 182 if (error != mojom::FileError::OK) { |
| 179 callback.Run(error); | 183 callback.Run(error); |
| 180 return; | 184 return; |
| 181 } | 185 } |
| 182 | 186 |
| 183 bool recursive = delete_flags & kDeleteFlagRecursive; | 187 bool recursive = delete_flags & mojom::kDeleteFlagRecursive; |
| 184 if (!base::DeleteFile(path, recursive)) { | 188 if (!base::DeleteFile(path, recursive)) { |
| 185 callback.Run(FileError::FAILED); | 189 callback.Run(mojom::FileError::FAILED); |
| 186 return; | 190 return; |
| 187 } | 191 } |
| 188 | 192 |
| 189 callback.Run(FileError::OK); | 193 callback.Run(mojom::FileError::OK); |
| 190 } | 194 } |
| 191 | 195 |
| 192 void DirectoryImpl::Exists(const mojo::String& raw_path, | 196 void DirectoryImpl::Exists(const mojo::String& raw_path, |
| 193 const ExistsCallback& callback) { | 197 const ExistsCallback& callback) { |
| 194 base::FilePath path; | 198 base::FilePath path; |
| 195 FileError error = ValidatePath(raw_path, directory_path_, &path); | 199 mojom::FileError error = ValidatePath(raw_path, directory_path_, &path); |
| 196 if (error != FileError::OK) { | 200 if (error != mojom::FileError::OK) { |
| 197 callback.Run(error, false); | 201 callback.Run(error, false); |
| 198 return; | 202 return; |
| 199 } | 203 } |
| 200 | 204 |
| 201 bool exists = base::PathExists(path); | 205 bool exists = base::PathExists(path); |
| 202 callback.Run(FileError::OK, exists); | 206 callback.Run(mojom::FileError::OK, exists); |
| 203 } | 207 } |
| 204 | 208 |
| 205 void DirectoryImpl::IsWritable(const mojo::String& raw_path, | 209 void DirectoryImpl::IsWritable(const mojo::String& raw_path, |
| 206 const IsWritableCallback& callback) { | 210 const IsWritableCallback& callback) { |
| 207 base::FilePath path; | 211 base::FilePath path; |
| 208 FileError error = ValidatePath(raw_path, directory_path_, &path); | 212 mojom::FileError error = ValidatePath(raw_path, directory_path_, &path); |
| 209 if (error != FileError::OK) { | 213 if (error != mojom::FileError::OK) { |
| 210 callback.Run(error, false); | 214 callback.Run(error, false); |
| 211 return; | 215 return; |
| 212 } | 216 } |
| 213 | 217 |
| 214 callback.Run(FileError::OK, base::PathIsWritable(path)); | 218 callback.Run(mojom::FileError::OK, base::PathIsWritable(path)); |
| 215 } | 219 } |
| 216 | 220 |
| 217 void DirectoryImpl::Flush(const FlushCallback& callback) { | 221 void DirectoryImpl::Flush(const FlushCallback& callback) { |
| 218 base::File file(directory_path_, base::File::FLAG_READ); | 222 base::File file(directory_path_, base::File::FLAG_READ); |
| 219 if (!file.IsValid()) { | 223 if (!file.IsValid()) { |
| 220 callback.Run(GetError(file)); | 224 callback.Run(GetError(file)); |
| 221 return; | 225 return; |
| 222 } | 226 } |
| 223 | 227 |
| 224 if (!file.Flush()) { | 228 if (!file.Flush()) { |
| 225 callback.Run(FileError::FAILED); | 229 callback.Run(mojom::FileError::FAILED); |
| 226 return; | 230 return; |
| 227 } | 231 } |
| 228 | 232 |
| 229 callback.Run(FileError::OK); | 233 callback.Run(mojom::FileError::OK); |
| 230 } | 234 } |
| 231 | 235 |
| 232 void DirectoryImpl::StatFile(const mojo::String& raw_path, | 236 void DirectoryImpl::StatFile(const mojo::String& raw_path, |
| 233 const StatFileCallback& callback) { | 237 const StatFileCallback& callback) { |
| 234 base::FilePath path; | 238 base::FilePath path; |
| 235 FileError error = ValidatePath(raw_path, directory_path_, &path); | 239 mojom::FileError error = ValidatePath(raw_path, directory_path_, &path); |
| 236 if (error != FileError::OK) { | 240 if (error != mojom::FileError::OK) { |
| 237 callback.Run(error, nullptr); | 241 callback.Run(error, nullptr); |
| 238 return; | 242 return; |
| 239 } | 243 } |
| 240 | 244 |
| 241 base::File base_file(path, base::File::FLAG_OPEN | base::File::FLAG_READ); | 245 base::File base_file(path, base::File::FLAG_OPEN | base::File::FLAG_READ); |
| 242 if (!base_file.IsValid()) { | 246 if (!base_file.IsValid()) { |
| 243 callback.Run(GetError(base_file), nullptr); | 247 callback.Run(GetError(base_file), nullptr); |
| 244 return; | 248 return; |
| 245 } | 249 } |
| 246 | 250 |
| 247 base::File::Info info; | 251 base::File::Info info; |
| 248 if (!base_file.GetInfo(&info)) { | 252 if (!base_file.GetInfo(&info)) { |
| 249 callback.Run(FileError::FAILED, nullptr); | 253 callback.Run(mojom::FileError::FAILED, nullptr); |
| 250 return; | 254 return; |
| 251 } | 255 } |
| 252 | 256 |
| 253 callback.Run(FileError::OK, MakeFileInformation(info)); | 257 callback.Run(mojom::FileError::OK, MakeFileInformation(info)); |
| 254 } | 258 } |
| 255 | 259 |
| 256 void DirectoryImpl::Clone(mojo::InterfaceRequest<Directory> directory) { | 260 void DirectoryImpl::Clone(mojo::InterfaceRequest<mojom::Directory> directory) { |
| 257 if (directory.is_pending()) { | 261 if (directory.is_pending()) { |
| 258 new DirectoryImpl(std::move(directory), directory_path_, | 262 new DirectoryImpl(std::move(directory), directory_path_, |
| 259 temp_dir_, lock_table_); | 263 temp_dir_, lock_table_); |
| 260 } | 264 } |
| 261 } | 265 } |
| 262 | 266 |
| 263 void DirectoryImpl::ReadEntireFile(const mojo::String& raw_path, | 267 void DirectoryImpl::ReadEntireFile(const mojo::String& raw_path, |
| 264 const ReadEntireFileCallback& callback) { | 268 const ReadEntireFileCallback& callback) { |
| 265 base::FilePath path; | 269 base::FilePath path; |
| 266 FileError error = ValidatePath(raw_path, directory_path_, &path); | 270 mojom::FileError error = ValidatePath(raw_path, directory_path_, &path); |
| 267 if (error != FileError::OK) { | 271 if (error != mojom::FileError::OK) { |
| 268 callback.Run(error, mojo::Array<uint8_t>()); | 272 callback.Run(error, mojo::Array<uint8_t>()); |
| 269 return; | 273 return; |
| 270 } | 274 } |
| 271 | 275 |
| 272 if (base::DirectoryExists(path)) { | 276 if (base::DirectoryExists(path)) { |
| 273 callback.Run(FileError::NOT_A_FILE, mojo::Array<uint8_t>()); | 277 callback.Run(mojom::FileError::NOT_A_FILE, mojo::Array<uint8_t>()); |
| 274 return; | 278 return; |
| 275 } | 279 } |
| 276 | 280 |
| 277 base::File base_file(path, base::File::FLAG_OPEN | base::File::FLAG_READ); | 281 base::File base_file(path, base::File::FLAG_OPEN | base::File::FLAG_READ); |
| 278 if (!base_file.IsValid()) { | 282 if (!base_file.IsValid()) { |
| 279 callback.Run(GetError(base_file), mojo::Array<uint8_t>()); | 283 callback.Run(GetError(base_file), mojo::Array<uint8_t>()); |
| 280 return; | 284 return; |
| 281 } | 285 } |
| 282 | 286 |
| 283 std::string contents; | 287 std::string contents; |
| 284 const int kBufferSize = 1 << 16; | 288 const int kBufferSize = 1 << 16; |
| 285 std::unique_ptr<char[]> buf(new char[kBufferSize]); | 289 std::unique_ptr<char[]> buf(new char[kBufferSize]); |
| 286 int len; | 290 int len; |
| 287 while ((len = base_file.ReadAtCurrentPos(buf.get(), kBufferSize)) > 0) | 291 while ((len = base_file.ReadAtCurrentPos(buf.get(), kBufferSize)) > 0) |
| 288 contents.append(buf.get(), len); | 292 contents.append(buf.get(), len); |
| 289 | 293 |
| 290 callback.Run(FileError::OK, mojo::Array<uint8_t>::From(contents)); | 294 callback.Run(mojom::FileError::OK, mojo::Array<uint8_t>::From(contents)); |
| 291 } | 295 } |
| 292 | 296 |
| 293 void DirectoryImpl::WriteFile(const mojo::String& raw_path, | 297 void DirectoryImpl::WriteFile(const mojo::String& raw_path, |
| 294 mojo::Array<uint8_t> data, | 298 mojo::Array<uint8_t> data, |
| 295 const WriteFileCallback& callback) { | 299 const WriteFileCallback& callback) { |
| 296 base::FilePath path; | 300 base::FilePath path; |
| 297 FileError error = ValidatePath(raw_path, directory_path_, &path); | 301 mojom::FileError error = ValidatePath(raw_path, directory_path_, &path); |
| 298 if (error != FileError::OK) { | 302 if (error != mojom::FileError::OK) { |
| 299 callback.Run(error); | 303 callback.Run(error); |
| 300 return; | 304 return; |
| 301 } | 305 } |
| 302 | 306 |
| 303 if (base::DirectoryExists(path)) { | 307 if (base::DirectoryExists(path)) { |
| 304 callback.Run(FileError::NOT_A_FILE); | 308 callback.Run(mojom::FileError::NOT_A_FILE); |
| 305 return; | 309 return; |
| 306 } | 310 } |
| 307 | 311 |
| 308 base::File base_file(path, | 312 base::File base_file(path, |
| 309 base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE); | 313 base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE); |
| 310 if (!base_file.IsValid()) { | 314 if (!base_file.IsValid()) { |
| 311 callback.Run(GetError(base_file)); | 315 callback.Run(GetError(base_file)); |
| 312 return; | 316 return; |
| 313 } | 317 } |
| 314 | 318 |
| 315 // If we're given empty data, we don't write and just truncate the file. | 319 // If we're given empty data, we don't write and just truncate the file. |
| 316 if (data.size()) { | 320 if (data.size()) { |
| 317 const int data_size = static_cast<int>(data.size()); | 321 const int data_size = static_cast<int>(data.size()); |
| 318 if (base_file.Write(0, reinterpret_cast<char*>(&data.front()), | 322 if (base_file.Write(0, reinterpret_cast<char*>(&data.front()), |
| 319 data_size) == -1) { | 323 data_size) == -1) { |
| 320 callback.Run(GetError(base_file)); | 324 callback.Run(GetError(base_file)); |
| 321 return; | 325 return; |
| 322 } | 326 } |
| 323 } | 327 } |
| 324 | 328 |
| 325 callback.Run(FileError::OK); | 329 callback.Run(mojom::FileError::OK); |
| 326 } | 330 } |
| 327 | 331 |
| 328 mojo::ScopedHandle DirectoryImpl::OpenFileHandleImpl( | 332 mojo::ScopedHandle DirectoryImpl::OpenFileHandleImpl( |
| 329 const mojo::String& raw_path, | 333 const mojo::String& raw_path, |
| 330 uint32_t open_flags, | 334 uint32_t open_flags, |
| 331 FileError* error) { | 335 mojom::FileError* error) { |
| 332 base::FilePath path; | 336 base::FilePath path; |
| 333 *error = ValidatePath(raw_path, directory_path_, &path); | 337 *error = ValidatePath(raw_path, directory_path_, &path); |
| 334 if (*error != FileError::OK) | 338 if (*error != mojom::FileError::OK) |
| 335 return mojo::ScopedHandle(); | 339 return mojo::ScopedHandle(); |
| 336 | 340 |
| 337 if (base::DirectoryExists(path)) { | 341 if (base::DirectoryExists(path)) { |
| 338 // We must not return directories as files. In the file abstraction, we | 342 // We must not return directories as files. In the file abstraction, we |
| 339 // can fetch raw file descriptors over mojo pipes, and passing a file | 343 // can fetch raw file descriptors over mojo pipes, and passing a file |
| 340 // descriptor to a directory is a sandbox escape on Windows. | 344 // descriptor to a directory is a sandbox escape on Windows. |
| 341 *error = FileError::NOT_A_FILE; | 345 *error = mojom::FileError::NOT_A_FILE; |
| 342 return mojo::ScopedHandle(); | 346 return mojo::ScopedHandle(); |
| 343 } | 347 } |
| 344 | 348 |
| 345 base::File base_file(path, open_flags); | 349 base::File base_file(path, open_flags); |
| 346 if (!base_file.IsValid()) { | 350 if (!base_file.IsValid()) { |
| 347 *error = GetError(base_file); | 351 *error = GetError(base_file); |
| 348 return mojo::ScopedHandle(); | 352 return mojo::ScopedHandle(); |
| 349 } | 353 } |
| 350 | 354 |
| 351 MojoHandle mojo_handle; | 355 MojoHandle mojo_handle; |
| 352 MojoResult create_result = MojoCreatePlatformHandleWrapper( | 356 MojoResult create_result = MojoCreatePlatformHandleWrapper( |
| 353 base_file.TakePlatformFile(), &mojo_handle); | 357 base_file.TakePlatformFile(), &mojo_handle); |
| 354 if (create_result != MOJO_RESULT_OK) { | 358 if (create_result != MOJO_RESULT_OK) { |
| 355 *error = FileError::FAILED; | 359 *error = mojom::FileError::FAILED; |
| 356 return mojo::ScopedHandle(); | 360 return mojo::ScopedHandle(); |
| 357 } | 361 } |
| 358 | 362 |
| 359 *error = FileError::OK; | 363 *error = mojom::FileError::OK; |
| 360 return mojo::ScopedHandle(mojo::Handle(mojo_handle)); | 364 return mojo::ScopedHandle(mojo::Handle(mojo_handle)); |
| 361 } | 365 } |
| 362 | 366 |
| 363 } // namespace filesystem | 367 } // namespace filesystem |
| OLD | NEW |