| 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 19 matching lines...) Expand all Loading... |
| 30 | 30 |
| 31 void DirectoryImpl::Read(const ReadCallback& callback) { | 31 void DirectoryImpl::Read(const ReadCallback& callback) { |
| 32 mojo::Array<DirectoryEntryPtr> entries(0); | 32 mojo::Array<DirectoryEntryPtr> entries(0); |
| 33 base::FileEnumerator directory_enumerator( | 33 base::FileEnumerator directory_enumerator( |
| 34 directory_path_, false, | 34 directory_path_, false, |
| 35 base::FileEnumerator::DIRECTORIES | base::FileEnumerator::FILES); | 35 base::FileEnumerator::DIRECTORIES | base::FileEnumerator::FILES); |
| 36 for (base::FilePath name = directory_enumerator.Next(); !name.empty(); | 36 for (base::FilePath name = directory_enumerator.Next(); !name.empty(); |
| 37 name = directory_enumerator.Next()) { | 37 name = directory_enumerator.Next()) { |
| 38 base::FileEnumerator::FileInfo info = directory_enumerator.GetInfo(); | 38 base::FileEnumerator::FileInfo info = directory_enumerator.GetInfo(); |
| 39 DirectoryEntryPtr entry = DirectoryEntry::New(); | 39 DirectoryEntryPtr entry = DirectoryEntry::New(); |
| 40 entry->type = info.IsDirectory() | 40 entry->type = |
| 41 ? FS_FILE_TYPE_DIRECTORY : FS_FILE_TYPE_REGULAR_FILE; | 41 info.IsDirectory() ? FsFileType::DIRECTORY : FsFileType::REGULAR_FILE; |
| 42 entry->name = info.GetName().AsUTF8Unsafe(); | 42 entry->name = info.GetName().AsUTF8Unsafe(); |
| 43 entries.push_back(std::move(entry)); | 43 entries.push_back(std::move(entry)); |
| 44 } | 44 } |
| 45 | 45 |
| 46 callback.Run(FILE_ERROR_OK, std::move(entries)); | 46 callback.Run(FileError::OK, std::move(entries)); |
| 47 } | 47 } |
| 48 | 48 |
| 49 // TODO(erg): Consider adding an implementation of Stat()/Touch() to the | 49 // TODO(erg): Consider adding an implementation of Stat()/Touch() to the |
| 50 // directory, too. Right now, the base::File abstractions do not really deal | 50 // directory, too. Right now, the base::File abstractions do not really deal |
| 51 // with directories properly, so these are broken for now. | 51 // with directories properly, so these are broken for now. |
| 52 | 52 |
| 53 // TODO(vtl): Move the implementation to a thread pool. | 53 // TODO(vtl): Move the implementation to a thread pool. |
| 54 void DirectoryImpl::OpenFile(const mojo::String& raw_path, | 54 void DirectoryImpl::OpenFile(const mojo::String& raw_path, |
| 55 mojo::InterfaceRequest<File> file, | 55 mojo::InterfaceRequest<File> file, |
| 56 uint32_t open_flags, | 56 uint32_t open_flags, |
| 57 const OpenFileCallback& callback) { | 57 const OpenFileCallback& callback) { |
| 58 base::FilePath path; | 58 base::FilePath path; |
| 59 if (FileError error = ValidatePath(raw_path, directory_path_, &path)) { | 59 FileError error = ValidatePath(raw_path, directory_path_, &path); |
| 60 if (error != FileError::OK) { |
| 60 callback.Run(error); | 61 callback.Run(error); |
| 61 return; | 62 return; |
| 62 } | 63 } |
| 63 | 64 |
| 64 #if defined(OS_WIN) | 65 #if defined(OS_WIN) |
| 65 // On Windows, FILE_FLAG_BACKUP_SEMANTICS is needed to open a directory. | 66 // On Windows, FILE_FLAG_BACKUP_SEMANTICS is needed to open a directory. |
| 66 if (DirectoryExists(path)) | 67 if (DirectoryExists(path)) |
| 67 open_flags |= base::File::FLAG_BACKUP_SEMANTICS; | 68 open_flags |= base::File::FLAG_BACKUP_SEMANTICS; |
| 68 #endif // OS_WIN | 69 #endif // OS_WIN |
| 69 | 70 |
| 70 base::File base_file(path, open_flags); | 71 base::File base_file(path, open_flags); |
| 71 if (!base_file.IsValid()) { | 72 if (!base_file.IsValid()) { |
| 72 callback.Run(FILE_ERROR_FAILED); | 73 callback.Run(FileError::FAILED); |
| 73 return; | 74 return; |
| 74 } | 75 } |
| 75 | 76 |
| 76 base::File::Info info; | 77 base::File::Info info; |
| 77 if (!base_file.GetInfo(&info)) { | 78 if (!base_file.GetInfo(&info)) { |
| 78 callback.Run(FILE_ERROR_FAILED); | 79 callback.Run(FileError::FAILED); |
| 79 return; | 80 return; |
| 80 } | 81 } |
| 81 | 82 |
| 82 if (info.is_directory) { | 83 if (info.is_directory) { |
| 83 // We must not return directories as files. In the file abstraction, we can | 84 // We must not return directories as files. In the file abstraction, we can |
| 84 // fetch raw file descriptors over mojo pipes, and passing a file | 85 // fetch raw file descriptors over mojo pipes, and passing a file |
| 85 // descriptor to a directory is a sandbox escape on Windows. | 86 // descriptor to a directory is a sandbox escape on Windows. |
| 86 callback.Run(FILE_ERROR_NOT_A_FILE); | 87 callback.Run(FileError::NOT_A_FILE); |
| 87 return; | 88 return; |
| 88 } | 89 } |
| 89 | 90 |
| 90 if (file.is_pending()) { | 91 if (file.is_pending()) { |
| 91 new FileImpl(std::move(file), std::move(base_file)); | 92 new FileImpl(std::move(file), std::move(base_file)); |
| 92 } | 93 } |
| 93 callback.Run(FILE_ERROR_OK); | 94 callback.Run(FileError::OK); |
| 94 } | 95 } |
| 95 | 96 |
| 96 void DirectoryImpl::OpenDirectory(const mojo::String& raw_path, | 97 void DirectoryImpl::OpenDirectory(const mojo::String& raw_path, |
| 97 mojo::InterfaceRequest<Directory> directory, | 98 mojo::InterfaceRequest<Directory> directory, |
| 98 uint32_t open_flags, | 99 uint32_t open_flags, |
| 99 const OpenDirectoryCallback& callback) { | 100 const OpenDirectoryCallback& callback) { |
| 100 base::FilePath path; | 101 base::FilePath path; |
| 101 if (FileError error = ValidatePath(raw_path, directory_path_, &path)) { | 102 FileError error = ValidatePath(raw_path, directory_path_, &path); |
| 103 if (error != FileError::OK) { |
| 102 callback.Run(error); | 104 callback.Run(error); |
| 103 return; | 105 return; |
| 104 } | 106 } |
| 105 | 107 |
| 106 if (!base::DirectoryExists(path)) { | 108 if (!base::DirectoryExists(path)) { |
| 107 if (base::PathExists(path)) { | 109 if (base::PathExists(path)) { |
| 108 callback.Run(FILE_ERROR_NOT_A_DIRECTORY); | 110 callback.Run(FileError::NOT_A_DIRECTORY); |
| 109 return; | 111 return; |
| 110 } | 112 } |
| 111 | 113 |
| 112 if (!(open_flags & kFlagOpenAlways || open_flags & kFlagCreate)) { | 114 if (!(open_flags & kFlagOpenAlways || open_flags & kFlagCreate)) { |
| 113 // The directory doesn't exist, and we weren't passed parameters to | 115 // The directory doesn't exist, and we weren't passed parameters to |
| 114 // create it. | 116 // create it. |
| 115 callback.Run(FILE_ERROR_NOT_FOUND); | 117 callback.Run(FileError::NOT_FOUND); |
| 116 return; | 118 return; |
| 117 } | 119 } |
| 118 | 120 |
| 119 base::File::Error error; | 121 base::File::Error error; |
| 120 if (!base::CreateDirectoryAndGetError(path, &error)) { | 122 if (!base::CreateDirectoryAndGetError(path, &error)) { |
| 121 callback.Run(static_cast<filesystem::FileError>(error)); | 123 callback.Run(static_cast<filesystem::FileError>(error)); |
| 122 return; | 124 return; |
| 123 } | 125 } |
| 124 } | 126 } |
| 125 | 127 |
| 126 if (directory.is_pending()) | 128 if (directory.is_pending()) |
| 127 new DirectoryImpl(std::move(directory), path, | 129 new DirectoryImpl(std::move(directory), path, |
| 128 scoped_ptr<base::ScopedTempDir>()); | 130 scoped_ptr<base::ScopedTempDir>()); |
| 129 callback.Run(FILE_ERROR_OK); | 131 callback.Run(FileError::OK); |
| 130 } | 132 } |
| 131 | 133 |
| 132 void DirectoryImpl::Rename(const mojo::String& raw_old_path, | 134 void DirectoryImpl::Rename(const mojo::String& raw_old_path, |
| 133 const mojo::String& raw_new_path, | 135 const mojo::String& raw_new_path, |
| 134 const RenameCallback& callback) { | 136 const RenameCallback& callback) { |
| 135 base::FilePath old_path; | 137 base::FilePath old_path; |
| 136 if (FileError error = | 138 FileError error = ValidatePath(raw_old_path, directory_path_, &old_path); |
| 137 ValidatePath(raw_old_path, directory_path_, &old_path)) { | 139 if (error != FileError::OK) { |
| 138 callback.Run(error); | 140 callback.Run(error); |
| 139 return; | 141 return; |
| 140 } | 142 } |
| 141 | 143 |
| 142 base::FilePath new_path; | 144 base::FilePath new_path; |
| 143 if (FileError error = | 145 error = ValidatePath(raw_new_path, directory_path_, &new_path); |
| 144 ValidatePath(raw_new_path, directory_path_, &new_path)) { | 146 if (error != FileError::OK) { |
| 145 callback.Run(error); | 147 callback.Run(error); |
| 146 return; | 148 return; |
| 147 } | 149 } |
| 148 | 150 |
| 149 if (!base::Move(old_path, new_path)) { | 151 if (!base::Move(old_path, new_path)) { |
| 150 callback.Run(FILE_ERROR_FAILED); | 152 callback.Run(FileError::FAILED); |
| 151 return; | 153 return; |
| 152 } | 154 } |
| 153 | 155 |
| 154 callback.Run(FILE_ERROR_OK); | 156 callback.Run(FileError::OK); |
| 155 } | 157 } |
| 156 | 158 |
| 157 void DirectoryImpl::Delete(const mojo::String& raw_path, | 159 void DirectoryImpl::Delete(const mojo::String& raw_path, |
| 158 uint32_t delete_flags, | 160 uint32_t delete_flags, |
| 159 const DeleteCallback& callback) { | 161 const DeleteCallback& callback) { |
| 160 base::FilePath path; | 162 base::FilePath path; |
| 161 if (FileError error = ValidatePath(raw_path, directory_path_, &path)) { | 163 FileError error = ValidatePath(raw_path, directory_path_, &path); |
| 164 if (error != FileError::OK) { |
| 162 callback.Run(error); | 165 callback.Run(error); |
| 163 return; | 166 return; |
| 164 } | 167 } |
| 165 | 168 |
| 166 bool recursive = delete_flags & kDeleteFlagRecursive; | 169 bool recursive = delete_flags & kDeleteFlagRecursive; |
| 167 if (!base::DeleteFile(path, recursive)) { | 170 if (!base::DeleteFile(path, recursive)) { |
| 168 callback.Run(FILE_ERROR_FAILED); | 171 callback.Run(FileError::FAILED); |
| 169 return; | 172 return; |
| 170 } | 173 } |
| 171 | 174 |
| 172 callback.Run(FILE_ERROR_OK); | 175 callback.Run(FileError::OK); |
| 173 } | 176 } |
| 174 | 177 |
| 175 void DirectoryImpl::Exists(const mojo::String& raw_path, | 178 void DirectoryImpl::Exists(const mojo::String& raw_path, |
| 176 const ExistsCallback& callback) { | 179 const ExistsCallback& callback) { |
| 177 base::FilePath path; | 180 base::FilePath path; |
| 178 if (FileError error = ValidatePath(raw_path, directory_path_, &path)) { | 181 FileError error = ValidatePath(raw_path, directory_path_, &path); |
| 182 if (error != FileError::OK) { |
| 179 callback.Run(error, false); | 183 callback.Run(error, false); |
| 180 return; | 184 return; |
| 181 } | 185 } |
| 182 | 186 |
| 183 bool exists = base::PathExists(path); | 187 bool exists = base::PathExists(path); |
| 184 callback.Run(FILE_ERROR_OK, exists); | 188 callback.Run(FileError::OK, exists); |
| 185 } | 189 } |
| 186 | 190 |
| 187 void DirectoryImpl::IsWritable(const mojo::String& raw_path, | 191 void DirectoryImpl::IsWritable(const mojo::String& raw_path, |
| 188 const IsWritableCallback& callback) { | 192 const IsWritableCallback& callback) { |
| 189 base::FilePath path; | 193 base::FilePath path; |
| 190 if (FileError error = ValidatePath(raw_path, directory_path_, &path)) { | 194 FileError error = ValidatePath(raw_path, directory_path_, &path); |
| 195 if (error != FileError::OK) { |
| 191 callback.Run(error, false); | 196 callback.Run(error, false); |
| 192 return; | 197 return; |
| 193 } | 198 } |
| 194 | 199 |
| 195 callback.Run(FILE_ERROR_OK, base::PathIsWritable(path)); | 200 callback.Run(FileError::OK, base::PathIsWritable(path)); |
| 196 } | 201 } |
| 197 | 202 |
| 198 void DirectoryImpl::Flush(const FlushCallback& callback) { | 203 void DirectoryImpl::Flush(const FlushCallback& callback) { |
| 199 base::File file(directory_path_, base::File::FLAG_READ); | 204 base::File file(directory_path_, base::File::FLAG_READ); |
| 200 if (!file.IsValid()) { | 205 if (!file.IsValid()) { |
| 201 callback.Run(FILE_ERROR_FAILED); | 206 callback.Run(FileError::FAILED); |
| 202 return; | 207 return; |
| 203 } | 208 } |
| 204 | 209 |
| 205 if (!file.Flush()) { | 210 if (!file.Flush()) { |
| 206 callback.Run(FILE_ERROR_FAILED); | 211 callback.Run(FileError::FAILED); |
| 207 return; | 212 return; |
| 208 } | 213 } |
| 209 | 214 |
| 210 callback.Run(FILE_ERROR_OK); | 215 callback.Run(FileError::OK); |
| 211 } | 216 } |
| 212 | 217 |
| 213 } // namespace filesystem | 218 } // namespace filesystem |
| OLD | NEW |