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