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_node.h" | 5 #include "nacl_io/html5fs/html5_fs_node.h" |
6 | 6 |
7 #include <errno.h> | 7 #include <errno.h> |
8 #include <fcntl.h> | 8 #include <fcntl.h> |
9 #include <ppapi/c/pp_completion_callback.h> | 9 #include <ppapi/c/pp_completion_callback.h> |
10 #include <ppapi/c/pp_directory_entry.h> | 10 #include <ppapi/c/pp_directory_entry.h> |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
69 return ppapi_flags; | 69 return ppapi_flags; |
70 } | 70 } |
71 | 71 |
72 } // namespace | 72 } // namespace |
73 | 73 |
74 Error Html5FsNode::FSync() { | 74 Error Html5FsNode::FSync() { |
75 // Cannot call Flush on a directory; simply do nothing. | 75 // Cannot call Flush on a directory; simply do nothing. |
76 if (IsaDir()) | 76 if (IsaDir()) |
77 return 0; | 77 return 0; |
78 | 78 |
79 int32_t result = filesystem_->ppapi()->GetFileIoInterface()->Flush( | 79 int32_t result = |
80 fileio_resource_, PP_BlockUntilComplete()); | 80 file_io_iface_->Flush(fileio_resource_, PP_BlockUntilComplete()); |
81 if (result != PP_OK) | 81 if (result != PP_OK) |
82 return PPErrorToErrno(result); | 82 return PPErrorToErrno(result); |
83 return 0; | 83 return 0; |
84 } | 84 } |
85 | 85 |
86 Error Html5FsNode::GetDents(size_t offs, | 86 Error Html5FsNode::GetDents(size_t offs, |
87 struct dirent* pdir, | 87 struct dirent* pdir, |
88 size_t size, | 88 size_t size, |
89 int* out_bytes) { | 89 int* out_bytes) { |
90 *out_bytes = 0; | 90 *out_bytes = 0; |
91 | 91 |
92 // If this is not a directory, fail | 92 // If this is not a directory, fail |
93 if (!IsaDir()) | 93 if (!IsaDir()) |
94 return ENOTDIR; | 94 return ENOTDIR; |
95 | 95 |
96 // TODO(binji): Better handling of ino numbers. | 96 // TODO(binji): Better handling of ino numbers. |
97 const ino_t kCurDirIno = -1; | 97 const ino_t kCurDirIno = -1; |
98 const ino_t kParentDirIno = -2; | 98 const ino_t kParentDirIno = -2; |
99 GetDentsHelper helper(kCurDirIno, kParentDirIno); | 99 GetDentsHelper helper(kCurDirIno, kParentDirIno); |
100 | 100 |
101 OutputBuffer output_buf = {NULL, 0}; | 101 OutputBuffer output_buf = {NULL, 0}; |
102 PP_ArrayOutput output = {&GetOutputBuffer, &output_buf}; | 102 PP_ArrayOutput output = {&GetOutputBuffer, &output_buf}; |
103 int32_t result = | 103 int32_t result = file_ref_iface_->ReadDirectoryEntries( |
104 filesystem_->ppapi()->GetFileRefInterface()->ReadDirectoryEntries( | 104 fileref_resource_, output, PP_BlockUntilComplete()); |
105 fileref_resource_, output, PP_BlockUntilComplete()); | |
106 if (result != PP_OK) | 105 if (result != PP_OK) |
107 return PPErrorToErrno(result); | 106 return PPErrorToErrno(result); |
108 | 107 |
109 PP_DirectoryEntry* entries = static_cast<PP_DirectoryEntry*>(output_buf.data); | 108 PP_DirectoryEntry* entries = static_cast<PP_DirectoryEntry*>(output_buf.data); |
110 | 109 |
111 for (int i = 0; i < output_buf.element_count; ++i) { | 110 for (int i = 0; i < output_buf.element_count; ++i) { |
112 PP_Var file_name_var = filesystem_->ppapi()->GetFileRefInterface()->GetName( | 111 PP_Var file_name_var = file_ref_iface_->GetName(entries[i].file_ref); |
113 entries[i].file_ref); | |
114 | 112 |
115 // Release the file reference. | 113 // Release the file reference. |
116 filesystem_->ppapi()->ReleaseResource(entries[i].file_ref); | 114 filesystem_->ppapi()->ReleaseResource(entries[i].file_ref); |
117 | 115 |
118 if (file_name_var.type != PP_VARTYPE_STRING) | 116 if (file_name_var.type != PP_VARTYPE_STRING) |
119 continue; | 117 continue; |
120 | 118 |
121 uint32_t file_name_length; | 119 uint32_t file_name_length; |
122 const char* file_name = filesystem_->ppapi()->GetVarInterface()->VarToUtf8( | 120 const char* file_name = |
123 file_name_var, &file_name_length); | 121 var_iface_->VarToUtf8(file_name_var, &file_name_length); |
124 | 122 |
125 if (file_name) { | 123 if (file_name) { |
126 file_name_length = | 124 file_name_length = |
127 std::min(static_cast<size_t>(file_name_length), | 125 std::min(static_cast<size_t>(file_name_length), |
128 MEMBER_SIZE(dirent, d_name) - 1); // -1 for NULL. | 126 MEMBER_SIZE(dirent, d_name) - 1); // -1 for NULL. |
129 | 127 |
130 // TODO(binji): Better handling of ino numbers. | 128 // TODO(binji): Better handling of ino numbers. |
131 helper.AddDirent(1, file_name, file_name_length); | 129 helper.AddDirent(1, file_name, file_name_length); |
132 } | 130 } |
133 | 131 |
134 filesystem_->ppapi()->GetVarInterface()->Release(file_name_var); | 132 var_iface_->Release(file_name_var); |
135 } | 133 } |
136 | 134 |
137 // Release the output buffer. | 135 // Release the output buffer. |
138 free(output_buf.data); | 136 free(output_buf.data); |
139 | 137 |
140 return helper.GetDents(offs, pdir, size, out_bytes); | 138 return helper.GetDents(offs, pdir, size, out_bytes); |
141 } | 139 } |
142 | 140 |
143 Error Html5FsNode::GetStat(struct stat* stat) { | 141 Error Html5FsNode::GetStat(struct stat* stat) { |
144 AUTO_LOCK(node_lock_); | 142 AUTO_LOCK(node_lock_); |
145 | 143 |
146 PP_FileInfo info; | 144 PP_FileInfo info; |
147 int32_t result = filesystem_->ppapi()->GetFileRefInterface()->Query( | 145 int32_t result = |
148 fileref_resource_, &info, PP_BlockUntilComplete()); | 146 file_ref_iface_->Query(fileref_resource_, &info, PP_BlockUntilComplete()); |
149 if (result != PP_OK) | 147 if (result != PP_OK) |
150 return PPErrorToErrno(result); | 148 return PPErrorToErrno(result); |
151 | 149 |
152 // Fill in known info here. | 150 // Fill in known info here. |
153 memcpy(stat, &stat_, sizeof(stat_)); | 151 memcpy(stat, &stat_, sizeof(stat_)); |
154 | 152 |
155 // Fill in the additional info from ppapi. | 153 // Fill in the additional info from ppapi. |
156 switch (info.type) { | 154 switch (info.type) { |
157 case PP_FILETYPE_REGULAR: | 155 case PP_FILETYPE_REGULAR: |
158 stat->st_mode |= S_IFREG; | 156 stat->st_mode |= S_IFREG; |
(...skipping 15 matching lines...) Expand all Loading... |
174 | 172 |
175 Error Html5FsNode::Read(const HandleAttr& attr, | 173 Error Html5FsNode::Read(const HandleAttr& attr, |
176 void* buf, | 174 void* buf, |
177 size_t count, | 175 size_t count, |
178 int* out_bytes) { | 176 int* out_bytes) { |
179 *out_bytes = 0; | 177 *out_bytes = 0; |
180 | 178 |
181 if (IsaDir()) | 179 if (IsaDir()) |
182 return EISDIR; | 180 return EISDIR; |
183 | 181 |
184 int32_t result = filesystem_->ppapi()->GetFileIoInterface()->Read( | 182 int32_t result = file_io_iface_->Read(fileio_resource_, |
185 fileio_resource_, | 183 attr.offs, |
186 attr.offs, | 184 static_cast<char*>(buf), |
187 static_cast<char*>(buf), | 185 static_cast<int32_t>(count), |
188 static_cast<int32_t>(count), | 186 PP_BlockUntilComplete()); |
189 PP_BlockUntilComplete()); | |
190 if (result < 0) | 187 if (result < 0) |
191 return PPErrorToErrno(result); | 188 return PPErrorToErrno(result); |
192 | 189 |
193 *out_bytes = result; | 190 *out_bytes = result; |
194 return 0; | 191 return 0; |
195 } | 192 } |
196 | 193 |
197 Error Html5FsNode::FTruncate(off_t size) { | 194 Error Html5FsNode::FTruncate(off_t size) { |
198 if (IsaDir()) | 195 if (IsaDir()) |
199 return EISDIR; | 196 return EISDIR; |
200 | 197 |
201 int32_t result = filesystem_->ppapi()->GetFileIoInterface()->SetLength( | 198 int32_t result = file_io_iface_->SetLength( |
202 fileio_resource_, size, PP_BlockUntilComplete()); | 199 fileio_resource_, size, PP_BlockUntilComplete()); |
203 if (result != PP_OK) | 200 if (result != PP_OK) |
204 return PPErrorToErrno(result); | 201 return PPErrorToErrno(result); |
205 return 0; | 202 return 0; |
206 } | 203 } |
207 | 204 |
208 Error Html5FsNode::Write(const HandleAttr& attr, | 205 Error Html5FsNode::Write(const HandleAttr& attr, |
209 const void* buf, | 206 const void* buf, |
210 size_t count, | 207 size_t count, |
211 int* out_bytes) { | 208 int* out_bytes) { |
212 *out_bytes = 0; | 209 *out_bytes = 0; |
213 | 210 |
214 if (IsaDir()) | 211 if (IsaDir()) |
215 return EISDIR; | 212 return EISDIR; |
216 | 213 |
217 int32_t result = filesystem_->ppapi()->GetFileIoInterface()->Write( | 214 int32_t result = file_io_iface_->Write(fileio_resource_, |
218 fileio_resource_, | 215 attr.offs, |
219 attr.offs, | 216 static_cast<const char*>(buf), |
220 static_cast<const char*>(buf), | 217 static_cast<int32_t>(count), |
221 static_cast<int32_t>(count), | 218 PP_BlockUntilComplete()); |
222 PP_BlockUntilComplete()); | |
223 if (result < 0) | 219 if (result < 0) |
224 return PPErrorToErrno(result); | 220 return PPErrorToErrno(result); |
225 | 221 |
226 *out_bytes = result; | 222 *out_bytes = result; |
227 return 0; | 223 return 0; |
228 } | 224 } |
229 | 225 |
230 int Html5FsNode::GetType() { | 226 int Html5FsNode::GetType() { |
231 return fileio_resource_ ? S_IFREG : S_IFDIR; | 227 return fileio_resource_ ? S_IFREG : S_IFDIR; |
232 } | 228 } |
233 | 229 |
234 Error Html5FsNode::GetSize(off_t* out_size) { | 230 Error Html5FsNode::GetSize(off_t* out_size) { |
235 *out_size = 0; | 231 *out_size = 0; |
236 | 232 |
237 if (IsaDir()) | 233 if (IsaDir()) |
238 return 0; | 234 return 0; |
239 | 235 |
240 AUTO_LOCK(node_lock_); | 236 AUTO_LOCK(node_lock_); |
241 | 237 |
242 PP_FileInfo info; | 238 PP_FileInfo info; |
243 int32_t result = filesystem_->ppapi()->GetFileIoInterface()->Query( | 239 int32_t result = |
244 fileio_resource_, &info, PP_BlockUntilComplete()); | 240 file_io_iface_->Query(fileio_resource_, &info, PP_BlockUntilComplete()); |
245 if (result != PP_OK) | 241 if (result != PP_OK) |
246 return PPErrorToErrno(result); | 242 return PPErrorToErrno(result); |
247 | 243 |
248 *out_size = info.size; | 244 *out_size = info.size; |
249 return 0; | 245 return 0; |
250 } | 246 } |
251 | 247 |
252 Html5FsNode::Html5FsNode(Filesystem* filesystem, PP_Resource fileref_resource) | 248 Html5FsNode::Html5FsNode(Filesystem* filesystem, PP_Resource fileref_resource) |
253 : Node(filesystem), | 249 : Node(filesystem), |
254 fileref_resource_(fileref_resource), | 250 fileref_resource_(fileref_resource), |
255 fileio_resource_(0) { | 251 fileio_resource_(0) { |
256 } | 252 } |
257 | 253 |
258 Error Html5FsNode::Init(int open_flags) { | 254 Error Html5FsNode::Init(int open_flags) { |
259 Error error = Node::Init(open_flags); | 255 Error error = Node::Init(open_flags); |
260 if (error) | 256 if (error) |
261 return error; | 257 return error; |
262 | 258 |
| 259 file_io_iface_ = filesystem_->ppapi()->GetFileIoInterface(); |
| 260 file_ref_iface_ = filesystem_->ppapi()->GetFileRefInterface(); |
| 261 var_iface_ = filesystem_->ppapi()->GetVarInterface(); |
| 262 |
| 263 if (!(file_io_iface_ && file_ref_iface_ && var_iface_)) { |
| 264 LOG_ERROR("Got NULL interface(s): %s%s%s", |
| 265 file_ref_iface_ ? "" : "FileRef", |
| 266 file_io_iface_ ? "" : "FileIo ", |
| 267 var_iface_ ? "" : "Var "); |
| 268 return EIO; |
| 269 } |
| 270 |
263 // First query the FileRef to see if it is a file or directory. | 271 // First query the FileRef to see if it is a file or directory. |
264 PP_FileInfo file_info; | 272 PP_FileInfo file_info; |
265 int32_t query_result = filesystem_->ppapi()->GetFileRefInterface()->Query( | 273 int32_t query_result = file_ref_iface_->Query( |
266 fileref_resource_, &file_info, PP_BlockUntilComplete()); | 274 fileref_resource_, &file_info, PP_BlockUntilComplete()); |
267 // If this is a directory, do not get a FileIO. | 275 // If this is a directory, do not get a FileIO. |
268 if (query_result == PP_OK && file_info.type == PP_FILETYPE_DIRECTORY) | 276 if (query_result == PP_OK && file_info.type == PP_FILETYPE_DIRECTORY) |
269 return 0; | 277 return 0; |
270 | 278 |
271 FileIoInterface* file_io = filesystem_->ppapi()->GetFileIoInterface(); | 279 fileio_resource_ = |
272 fileio_resource_ = file_io->Create(filesystem_->ppapi()->GetInstance()); | 280 file_io_iface_->Create(filesystem_->ppapi()->GetInstance()); |
273 if (!fileio_resource_) | 281 if (!fileio_resource_) { |
274 return ENOSYS; | 282 LOG_ERROR("Couldn't create FileIo resource."); |
| 283 return EIO; |
| 284 } |
275 | 285 |
276 int32_t open_result = file_io->Open(fileio_resource_, | 286 int32_t open_result = |
277 fileref_resource_, | 287 file_io_iface_->Open(fileio_resource_, |
278 OpenFlagsToPPAPIOpenFlags(open_flags), | 288 fileref_resource_, |
279 PP_BlockUntilComplete()); | 289 OpenFlagsToPPAPIOpenFlags(open_flags), |
| 290 PP_BlockUntilComplete()); |
280 if (open_result != PP_OK) | 291 if (open_result != PP_OK) |
281 return PPErrorToErrno(open_result); | 292 return PPErrorToErrno(open_result); |
282 return 0; | 293 return 0; |
283 } | 294 } |
284 | 295 |
285 void Html5FsNode::Destroy() { | 296 void Html5FsNode::Destroy() { |
286 FSync(); | 297 FSync(); |
287 | 298 |
288 if (fileio_resource_) { | 299 if (fileio_resource_) { |
289 filesystem_->ppapi()->GetFileIoInterface()->Close(fileio_resource_); | 300 file_io_iface_->Close(fileio_resource_); |
290 filesystem_->ppapi()->ReleaseResource(fileio_resource_); | 301 filesystem_->ppapi()->ReleaseResource(fileio_resource_); |
291 } | 302 } |
292 | 303 |
293 filesystem_->ppapi()->ReleaseResource(fileref_resource_); | 304 filesystem_->ppapi()->ReleaseResource(fileref_resource_); |
294 fileio_resource_ = 0; | 305 fileio_resource_ = 0; |
295 fileref_resource_ = 0; | 306 fileref_resource_ = 0; |
296 Node::Destroy(); | 307 Node::Destroy(); |
297 } | 308 } |
298 | 309 |
299 } // namespace nacl_io | 310 } // namespace nacl_io |
OLD | NEW |