OLD | NEW |
---|---|
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 "nacl_io/html5fs/html5_fs.h" | 5 #include "nacl_io/html5fs/html5_fs.h" |
6 | 6 |
7 #include <errno.h> | 7 #include <errno.h> |
8 #include <fcntl.h> | 8 #include <fcntl.h> |
9 #include <stdlib.h> | 9 #include <stdlib.h> |
10 #include <string.h> | 10 #include <string.h> |
(...skipping 23 matching lines...) Expand all Loading... | |
34 ScopedNode node; | 34 ScopedNode node; |
35 return Open(path, O_RDONLY, &node); | 35 return Open(path, O_RDONLY, &node); |
36 } | 36 } |
37 | 37 |
38 Error Html5Fs::Open(const Path& path, int open_flags, ScopedNode* out_node) { | 38 Error Html5Fs::Open(const Path& path, int open_flags, ScopedNode* out_node) { |
39 out_node->reset(NULL); | 39 out_node->reset(NULL); |
40 Error error = BlockUntilFilesystemOpen(); | 40 Error error = BlockUntilFilesystemOpen(); |
41 if (error) | 41 if (error) |
42 return error; | 42 return error; |
43 | 43 |
44 PP_Resource fileref = ppapi()->GetFileRefInterface()->Create( | 44 PP_Resource fileref = file_ref_iface_->Create( |
45 filesystem_resource_, GetFullPath(path).Join().c_str()); | 45 filesystem_resource_, GetFullPath(path).Join().c_str()); |
46 if (!fileref) | 46 if (!fileref) |
47 return ENOENT; | 47 return ENOENT; |
48 | 48 |
49 ScopedNode node(new Html5FsNode(this, fileref)); | 49 ScopedNode node(new Html5FsNode(this, fileref)); |
50 error = node->Init(open_flags); | 50 error = node->Init(open_flags); |
51 if (error) | 51 if (error) |
52 return error; | 52 return error; |
53 | 53 |
54 *out_node = node; | 54 *out_node = node; |
(...skipping 15 matching lines...) Expand all Loading... | |
70 if (error) | 70 if (error) |
71 return error; | 71 return error; |
72 | 72 |
73 // FileRef returns PP_ERROR_NOACCESS which is translated to EACCES if you | 73 // FileRef returns PP_ERROR_NOACCESS which is translated to EACCES if you |
74 // try to create the root directory. EEXIST is a better errno here. | 74 // try to create the root directory. EEXIST is a better errno here. |
75 if (path.IsRoot()) | 75 if (path.IsRoot()) |
76 return EEXIST; | 76 return EEXIST; |
77 | 77 |
78 ScopedResource fileref_resource( | 78 ScopedResource fileref_resource( |
79 ppapi(), | 79 ppapi(), |
80 ppapi()->GetFileRefInterface()->Create(filesystem_resource_, | 80 file_ref_iface_->Create(filesystem_resource_, |
81 GetFullPath(path).Join().c_str())); | 81 GetFullPath(path).Join().c_str())); |
82 if (!fileref_resource.pp_resource()) | 82 if (!fileref_resource.pp_resource()) |
83 return ENOENT; | 83 return ENOENT; |
84 | 84 |
85 int32_t result = ppapi()->GetFileRefInterface()->MakeDirectory( | 85 int32_t result = file_ref_iface_->MakeDirectory( |
86 fileref_resource.pp_resource(), PP_FALSE, PP_BlockUntilComplete()); | 86 fileref_resource.pp_resource(), PP_FALSE, PP_BlockUntilComplete()); |
87 if (result != PP_OK) | 87 if (result != PP_OK) |
88 return PPErrorToErrno(result); | 88 return PPErrorToErrno(result); |
89 | 89 |
90 return 0; | 90 return 0; |
91 } | 91 } |
92 | 92 |
93 Error Html5Fs::Rmdir(const Path& path) { | 93 Error Html5Fs::Rmdir(const Path& path) { |
94 return RemoveInternal(path, REMOVE_DIR); | 94 return RemoveInternal(path, REMOVE_DIR); |
95 } | 95 } |
96 | 96 |
97 Error Html5Fs::Remove(const Path& path) { | 97 Error Html5Fs::Remove(const Path& path) { |
98 return RemoveInternal(path, REMOVE_ALL); | 98 return RemoveInternal(path, REMOVE_ALL); |
99 } | 99 } |
100 | 100 |
101 Error Html5Fs::RemoveInternal(const Path& path, int remove_type) { | 101 Error Html5Fs::RemoveInternal(const Path& path, int remove_type) { |
102 Error error = BlockUntilFilesystemOpen(); | 102 Error error = BlockUntilFilesystemOpen(); |
103 if (error) | 103 if (error) |
104 return error; | 104 return error; |
105 | 105 |
106 ScopedResource fileref_resource( | 106 ScopedResource fileref_resource( |
107 ppapi(), | 107 ppapi(), |
108 ppapi()->GetFileRefInterface()->Create(filesystem_resource_, | 108 file_ref_iface_->Create(filesystem_resource_, |
109 GetFullPath(path).Join().c_str())); | 109 GetFullPath(path).Join().c_str())); |
110 if (!fileref_resource.pp_resource()) | 110 if (!fileref_resource.pp_resource()) |
111 return ENOENT; | 111 return ENOENT; |
112 | 112 |
113 // Check file type | 113 // Check file type |
114 if (remove_type != REMOVE_ALL) { | 114 if (remove_type != REMOVE_ALL) { |
115 PP_FileInfo file_info; | 115 PP_FileInfo file_info; |
116 int32_t query_result = ppapi()->GetFileRefInterface()->Query( | 116 int32_t query_result = file_ref_iface_->Query( |
117 fileref_resource.pp_resource(), &file_info, PP_BlockUntilComplete()); | 117 fileref_resource.pp_resource(), &file_info, PP_BlockUntilComplete()); |
118 if (query_result != PP_OK) { | 118 if (query_result != PP_OK) { |
119 LOG_ERROR("Error querying file type"); | 119 LOG_ERROR("Error querying file type"); |
120 return EINVAL; | 120 return EINVAL; |
121 } | 121 } |
122 switch (file_info.type) { | 122 switch (file_info.type) { |
123 case PP_FILETYPE_DIRECTORY: | 123 case PP_FILETYPE_DIRECTORY: |
124 if (!(remove_type & REMOVE_DIR)) | 124 if (!(remove_type & REMOVE_DIR)) |
125 return EISDIR; | 125 return EISDIR; |
126 break; | 126 break; |
127 case PP_FILETYPE_REGULAR: | 127 case PP_FILETYPE_REGULAR: |
128 if (!(remove_type & REMOVE_FILE)) | 128 if (!(remove_type & REMOVE_FILE)) |
129 return ENOTDIR; | 129 return ENOTDIR; |
130 break; | 130 break; |
131 default: | 131 default: |
132 LOG_ERROR("Invalid file type: %d", file_info.type); | 132 LOG_ERROR("Invalid file type: %d", file_info.type); |
133 return EINVAL; | 133 return EINVAL; |
134 } | 134 } |
135 } | 135 } |
136 | 136 |
137 int32_t result = ppapi()->GetFileRefInterface()->Delete( | 137 int32_t result = file_ref_iface_->Delete(fileref_resource.pp_resource(), |
138 fileref_resource.pp_resource(), PP_BlockUntilComplete()); | 138 PP_BlockUntilComplete()); |
139 if (result != PP_OK) | 139 if (result != PP_OK) |
140 return PPErrorToErrno(result); | 140 return PPErrorToErrno(result); |
141 | 141 |
142 return 0; | 142 return 0; |
143 } | 143 } |
144 | 144 |
145 Error Html5Fs::Rename(const Path& path, const Path& newpath) { | 145 Error Html5Fs::Rename(const Path& path, const Path& newpath) { |
146 Error error = BlockUntilFilesystemOpen(); | 146 Error error = BlockUntilFilesystemOpen(); |
147 if (error) | 147 if (error) |
148 return error; | 148 return error; |
149 | 149 |
150 const char* oldpath_full = GetFullPath(path).Join().c_str(); | 150 const char* oldpath_full = GetFullPath(path).Join().c_str(); |
151 ScopedResource fileref_resource( | 151 ScopedResource fileref_resource( |
152 ppapi(), | 152 ppapi(), file_ref_iface_->Create(filesystem_resource_, oldpath_full)); |
153 ppapi()->GetFileRefInterface()->Create(filesystem_resource_, | |
154 oldpath_full)); | |
155 if (!fileref_resource.pp_resource()) | 153 if (!fileref_resource.pp_resource()) |
156 return ENOENT; | 154 return ENOENT; |
157 | 155 |
158 const char* newpath_full = GetFullPath(newpath).Join().c_str(); | 156 const char* newpath_full = GetFullPath(newpath).Join().c_str(); |
159 ScopedResource new_fileref_resource( | 157 ScopedResource new_fileref_resource( |
160 ppapi(), | 158 ppapi(), file_ref_iface_->Create(filesystem_resource_, newpath_full)); |
161 ppapi()->GetFileRefInterface()->Create(filesystem_resource_, | |
162 newpath_full)); | |
163 if (!new_fileref_resource.pp_resource()) | 159 if (!new_fileref_resource.pp_resource()) |
164 return ENOENT; | 160 return ENOENT; |
165 | 161 |
166 int32_t result = | 162 int32_t result = file_ref_iface_->Rename(fileref_resource.pp_resource(), |
167 ppapi()->GetFileRefInterface()->Rename(fileref_resource.pp_resource(), | 163 new_fileref_resource.pp_resource(), |
168 new_fileref_resource.pp_resource(), | 164 PP_BlockUntilComplete()); |
169 PP_BlockUntilComplete()); | |
170 if (result != PP_OK) | 165 if (result != PP_OK) |
171 return PPErrorToErrno(result); | 166 return PPErrorToErrno(result); |
172 | 167 |
173 return 0; | 168 return 0; |
174 } | 169 } |
175 | 170 |
176 Html5Fs::Html5Fs() | 171 Html5Fs::Html5Fs() |
177 : filesystem_resource_(0), | 172 : filesystem_iface_(NULL), |
173 file_ref_iface_(NULL), | |
174 file_io_iface_(NULL), | |
175 filesystem_resource_(0), | |
178 filesystem_open_has_result_(false), | 176 filesystem_open_has_result_(false), |
179 filesystem_open_error_(0) { | 177 filesystem_open_error_(0) { |
180 } | 178 } |
181 | 179 |
182 Error Html5Fs::Init(const FsInitArgs& args) { | 180 Error Html5Fs::Init(const FsInitArgs& args) { |
183 Error error = Filesystem::Init(args); | 181 Error error = Filesystem::Init(args); |
184 if (error) | 182 if (error) |
185 return error; | 183 return error; |
186 | 184 |
187 if (!args.ppapi) | 185 if (!args.ppapi) { |
186 LOG_ERROR("ppapi is NULL."); | |
188 return ENOSYS; | 187 return ENOSYS; |
188 } | |
189 | |
190 core_iface_ = ppapi()->GetCoreInterface(); | |
191 filesystem_iface_ = ppapi()->GetFileSystemInterface(); | |
192 file_io_iface_ = ppapi()->GetFileIoInterface(); | |
193 file_ref_iface_ = ppapi()->GetFileRefInterface(); | |
194 | |
195 if (!(core_iface_ && filesystem_iface_ && file_io_iface_ && | |
196 file_ref_iface_)) { | |
197 LOG_ERROR("Got NULL interface(s): %s%s%s%s", | |
198 core_iface_ ? "" : "Core ", | |
199 filesystem_iface_ ? "" : "FileSystem ", | |
200 file_ref_iface_ ? "" : "FileRef", | |
201 file_io_iface_ ? "" : "FileIo "); | |
202 return ENOSYS; | |
203 } | |
189 | 204 |
190 pthread_cond_init(&filesystem_open_cond_, NULL); | 205 pthread_cond_init(&filesystem_open_cond_, NULL); |
191 | 206 |
192 // Parse filesystem args. | 207 // Parse filesystem args. |
193 PP_FileSystemType filesystem_type = PP_FILESYSTEMTYPE_LOCALPERSISTENT; | 208 PP_FileSystemType filesystem_type = PP_FILESYSTEMTYPE_LOCALPERSISTENT; |
194 int64_t expected_size = 0; | 209 int64_t expected_size = 0; |
195 for (StringMap_t::const_iterator iter = args.string_map.begin(); | 210 for (StringMap_t::const_iterator iter = args.string_map.begin(); |
196 iter != args.string_map.end(); | 211 iter != args.string_map.end(); |
197 ++iter) { | 212 ++iter) { |
198 if (iter->first == "type") { | 213 if (iter->first == "type") { |
199 if (iter->second == "PERSISTENT") { | 214 if (iter->second == "PERSISTENT") { |
200 filesystem_type = PP_FILESYSTEMTYPE_LOCALPERSISTENT; | 215 filesystem_type = PP_FILESYSTEMTYPE_LOCALPERSISTENT; |
201 } else if (iter->second == "TEMPORARY") { | 216 } else if (iter->second == "TEMPORARY") { |
202 filesystem_type = PP_FILESYSTEMTYPE_LOCALTEMPORARY; | 217 filesystem_type = PP_FILESYSTEMTYPE_LOCALTEMPORARY; |
203 } else if (iter->second == "") { | 218 } else if (iter->second == "") { |
204 filesystem_type = PP_FILESYSTEMTYPE_LOCALPERSISTENT; | 219 filesystem_type = PP_FILESYSTEMTYPE_LOCALPERSISTENT; |
205 } else { | 220 } else { |
206 LOG_ERROR("html5fs: unknown type: '%s'", iter->second.c_str()); | 221 LOG_ERROR("Unknown type: '%s'", iter->second.c_str()); |
Sam Clegg
2014/06/20 19:16:14
fstype?
binji
2014/06/20 19:38:30
Done.
| |
207 return EINVAL; | 222 return EINVAL; |
208 } | 223 } |
209 } else if (iter->first == "expected_size") { | 224 } else if (iter->first == "expected_size") { |
210 expected_size = strtoull(iter->second.c_str(), NULL, 10); | 225 expected_size = strtoull(iter->second.c_str(), NULL, 10); |
211 } else if (iter->first == "filesystem_resource") { | 226 } else if (iter->first == "filesystem_resource") { |
212 PP_Resource resource = strtoull(iter->second.c_str(), NULL, 10); | 227 PP_Resource resource = strtoull(iter->second.c_str(), NULL, 10); |
213 if (!ppapi_->GetFileSystemInterface()->IsFileSystem(resource)) | 228 if (!filesystem_iface_->IsFileSystem(resource)) |
214 return EINVAL; | 229 return EINVAL; |
215 | 230 |
216 filesystem_resource_ = resource; | 231 filesystem_resource_ = resource; |
217 ppapi_->AddRefResource(filesystem_resource_); | 232 ppapi_->AddRefResource(filesystem_resource_); |
218 } else if (iter->first == "SOURCE") { | 233 } else if (iter->first == "SOURCE") { |
219 prefix_ = iter->second; | 234 prefix_ = iter->second; |
220 } else { | 235 } else { |
221 LOG_ERROR("html5fs: bad param: %s", iter->first.c_str()); | 236 LOG_ERROR("Bad param: %s", iter->first.c_str()); |
Sam Clegg
2014/06/20 19:16:14
invalid fs option?
binji
2014/06/20 19:38:30
Done.
| |
222 return EINVAL; | 237 return EINVAL; |
223 } | 238 } |
224 } | 239 } |
225 | 240 |
226 if (filesystem_resource_ != 0) { | 241 if (filesystem_resource_ != 0) { |
227 filesystem_open_has_result_ = true; | 242 filesystem_open_has_result_ = true; |
228 filesystem_open_error_ = PP_OK; | 243 filesystem_open_error_ = PP_OK; |
229 return 0; | 244 return 0; |
230 } | 245 } |
231 | 246 |
232 // Initialize filesystem. | 247 // Initialize filesystem. |
233 filesystem_resource_ = ppapi_->GetFileSystemInterface()->Create( | 248 filesystem_resource_ = |
234 ppapi_->GetInstance(), filesystem_type); | 249 filesystem_iface_->Create(ppapi_->GetInstance(), filesystem_type); |
235 if (filesystem_resource_ == 0) | 250 if (filesystem_resource_ == 0) |
236 return ENOSYS; | 251 return ENOSYS; |
237 | 252 |
238 // We can't block the main thread, so make an asynchronous call if on main | 253 // We can't block the main thread, so make an asynchronous call if on main |
239 // thread. If we are off-main-thread, then don't make an asynchronous call; | 254 // thread. If we are off-main-thread, then don't make an asynchronous call; |
240 // otherwise we require a message loop. | 255 // otherwise we require a message loop. |
241 bool main_thread = ppapi_->GetCoreInterface()->IsMainThread(); | 256 bool main_thread = core_iface_->IsMainThread(); |
242 PP_CompletionCallback cc = | 257 PP_CompletionCallback cc = |
243 main_thread ? PP_MakeCompletionCallback( | 258 main_thread ? PP_MakeCompletionCallback( |
244 &Html5Fs::FilesystemOpenCallbackThunk, this) | 259 &Html5Fs::FilesystemOpenCallbackThunk, this) |
245 : PP_BlockUntilComplete(); | 260 : PP_BlockUntilComplete(); |
246 | 261 |
247 int32_t result = ppapi_->GetFileSystemInterface()->Open( | 262 int32_t result = |
248 filesystem_resource_, expected_size, cc); | 263 filesystem_iface_->Open(filesystem_resource_, expected_size, cc); |
249 | 264 |
250 if (!main_thread) { | 265 if (!main_thread) { |
251 filesystem_open_has_result_ = true; | 266 filesystem_open_has_result_ = true; |
252 filesystem_open_error_ = PPErrorToErrno(result); | 267 filesystem_open_error_ = PPErrorToErrno(result); |
253 | 268 |
254 return filesystem_open_error_; | 269 return filesystem_open_error_; |
255 } | 270 } |
256 | 271 |
257 // We have to assume the call to Open will succeed; there is no better | 272 // We have to assume the call to Open will succeed; there is no better |
258 // result to return here. | 273 // result to return here. |
(...skipping 20 matching lines...) Expand all Loading... | |
279 } | 294 } |
280 | 295 |
281 void Html5Fs::FilesystemOpenCallback(int32_t result) { | 296 void Html5Fs::FilesystemOpenCallback(int32_t result) { |
282 AUTO_LOCK(filesysem_open_lock_); | 297 AUTO_LOCK(filesysem_open_lock_); |
283 filesystem_open_has_result_ = true; | 298 filesystem_open_has_result_ = true; |
284 filesystem_open_error_ = PPErrorToErrno(result); | 299 filesystem_open_error_ = PPErrorToErrno(result); |
285 pthread_cond_signal(&filesystem_open_cond_); | 300 pthread_cond_signal(&filesystem_open_cond_); |
286 } | 301 } |
287 | 302 |
288 } // namespace nacl_io | 303 } // namespace nacl_io |
OLD | NEW |