| 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 |