| OLD | NEW |
| 1 /* Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 /* Copyright (c) 2012 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 | 5 |
| 6 #include "nacl_io/mount_node_html5fs.h" | 6 #include "nacl_io/mount_node_html5fs.h" |
| 7 | 7 |
| 8 #include <errno.h> | 8 #include <errno.h> |
| 9 #include <fcntl.h> | 9 #include <fcntl.h> |
| 10 #include <ppapi/c/pp_completion_callback.h> | 10 #include <ppapi/c/pp_completion_callback.h> |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 48 open_flags = PP_FILEOPENFLAG_READ; | 48 open_flags = PP_FILEOPENFLAG_READ; |
| 49 break; | 49 break; |
| 50 case O_WRONLY: | 50 case O_WRONLY: |
| 51 open_flags = PP_FILEOPENFLAG_WRITE; | 51 open_flags = PP_FILEOPENFLAG_WRITE; |
| 52 break; | 52 break; |
| 53 case O_RDWR: | 53 case O_RDWR: |
| 54 open_flags = PP_FILEOPENFLAG_READ | PP_FILEOPENFLAG_WRITE; | 54 open_flags = PP_FILEOPENFLAG_READ | PP_FILEOPENFLAG_WRITE; |
| 55 break; | 55 break; |
| 56 } | 56 } |
| 57 | 57 |
| 58 if (mode & O_CREAT) open_flags |= PP_FILEOPENFLAG_CREATE; | 58 if (mode & O_CREAT) |
| 59 if (mode & O_TRUNC) open_flags |= PP_FILEOPENFLAG_TRUNCATE; | 59 open_flags |= PP_FILEOPENFLAG_CREATE; |
| 60 if (mode & O_EXCL) open_flags |= PP_FILEOPENFLAG_EXCLUSIVE; | 60 if (mode & O_TRUNC) |
| 61 open_flags |= PP_FILEOPENFLAG_TRUNCATE; |
| 62 if (mode & O_EXCL) |
| 63 open_flags |= PP_FILEOPENFLAG_EXCLUSIVE; |
| 61 | 64 |
| 62 return open_flags; | 65 return open_flags; |
| 63 } | 66 } |
| 64 | 67 |
| 65 } // namespace | 68 } // namespace |
| 66 | 69 |
| 67 int MountNodeHtml5Fs::FSync() { | 70 Error MountNodeHtml5Fs::FSync() { |
| 68 int32_t result = mount_->ppapi()->GetFileIoInterface()->Flush( | 71 int32_t result = mount_->ppapi()->GetFileIoInterface() |
| 69 fileio_resource_, PP_BlockUntilComplete()); | 72 ->Flush(fileio_resource_, PP_BlockUntilComplete()); |
| 70 if (result != PP_OK) { | 73 if (result != PP_OK) |
| 71 errno = PPErrorToErrno(result); | 74 return PPErrorToErrno(result); |
| 72 return -1; | |
| 73 } | |
| 74 | |
| 75 return 0; | 75 return 0; |
| 76 } | 76 } |
| 77 | 77 |
| 78 int MountNodeHtml5Fs::GetDents(size_t offs, struct dirent* pdir, size_t size) { | 78 Error MountNodeHtml5Fs::GetDents(size_t offs, |
| 79 struct dirent* pdir, |
| 80 size_t size, |
| 81 int* out_bytes) { |
| 82 *out_bytes = 0; |
| 83 |
| 79 // If the buffer pointer is invalid, fail | 84 // If the buffer pointer is invalid, fail |
| 80 if (NULL == pdir) { | 85 if (NULL == pdir) |
| 81 errno = EINVAL; | 86 return EINVAL; |
| 82 return -1; | |
| 83 } | |
| 84 | 87 |
| 85 // If the buffer is too small, fail | 88 // If the buffer is too small, fail |
| 86 if (size < sizeof(struct dirent)) { | 89 if (size < sizeof(struct dirent)) |
| 87 errno = EINVAL; | 90 return EINVAL; |
| 88 return -1; | |
| 89 } | |
| 90 | 91 |
| 91 OutputBuffer output_buf = { NULL, 0 }; | 92 OutputBuffer output_buf = {NULL, 0}; |
| 92 PP_ArrayOutput output = { &GetOutputBuffer, &output_buf }; | 93 PP_ArrayOutput output = {&GetOutputBuffer, &output_buf}; |
| 93 int32_t result = | 94 int32_t result = mount_->ppapi()->GetFileRefInterface()->ReadDirectoryEntries( |
| 94 mount_->ppapi()->GetFileRefInterface()->ReadDirectoryEntries( | 95 fileref_resource_, output, PP_BlockUntilComplete()); |
| 95 fileref_resource_, output, PP_BlockUntilComplete()); | 96 if (result != PP_OK) |
| 96 if (result != PP_OK) { | 97 return PPErrorToErrno(result); |
| 97 errno = PPErrorToErrno(result); | |
| 98 return -1; | |
| 99 } | |
| 100 | 98 |
| 101 std::vector<struct dirent> dirents; | 99 std::vector<struct dirent> dirents; |
| 102 PP_DirectoryEntry* entries = | 100 PP_DirectoryEntry* entries = static_cast<PP_DirectoryEntry*>(output_buf.data); |
| 103 static_cast<PP_DirectoryEntry*>(output_buf.data); | |
| 104 | 101 |
| 105 for (int i = 0; i < output_buf.element_count; ++i) { | 102 for (int i = 0; i < output_buf.element_count; ++i) { |
| 106 PP_Var file_name_var = mount_->ppapi()->GetFileRefInterface()->GetName( | 103 PP_Var file_name_var = |
| 107 entries[i].file_ref); | 104 mount_->ppapi()->GetFileRefInterface()->GetName(entries[i].file_ref); |
| 108 | 105 |
| 109 // Release the file reference. | 106 // Release the file reference. |
| 110 mount_->ppapi()->ReleaseResource(entries[i].file_ref); | 107 mount_->ppapi()->ReleaseResource(entries[i].file_ref); |
| 111 | 108 |
| 112 if (file_name_var.type != PP_VARTYPE_STRING) | 109 if (file_name_var.type != PP_VARTYPE_STRING) |
| 113 continue; | 110 continue; |
| 114 | 111 |
| 115 uint32_t file_name_length; | 112 uint32_t file_name_length; |
| 116 const char* file_name = mount_->ppapi()->GetVarInterface()->VarToUtf8( | 113 const char* file_name = mount_->ppapi()->GetVarInterface() |
| 117 file_name_var, &file_name_length); | 114 ->VarToUtf8(file_name_var, &file_name_length); |
| 118 if (!file_name) | 115 if (!file_name) |
| 119 continue; | 116 continue; |
| 120 | 117 |
| 121 file_name_length = std::min( | 118 file_name_length = std::min( |
| 122 static_cast<size_t>(file_name_length), | 119 static_cast<size_t>(file_name_length), |
| 123 sizeof(static_cast<struct dirent*>(0)->d_name) - 1); // -1 for NULL. | 120 sizeof(static_cast<struct dirent*>(0)->d_name) - 1); // -1 for NULL. |
| 124 | 121 |
| 125 dirents.push_back(dirent()); | 122 dirents.push_back(dirent()); |
| 126 struct dirent& direntry = dirents.back(); | 123 struct dirent& direntry = dirents.back(); |
| 127 direntry.d_ino = 0; // TODO(binji): Is this needed? | 124 direntry.d_ino = 0; // TODO(binji): Is this needed? |
| 128 direntry.d_off = sizeof(struct dirent); | 125 direntry.d_off = sizeof(struct dirent); |
| 129 direntry.d_reclen = sizeof(struct dirent); | 126 direntry.d_reclen = sizeof(struct dirent); |
| 130 strncpy(direntry.d_name, file_name, file_name_length); | 127 strncpy(direntry.d_name, file_name, file_name_length); |
| 131 direntry.d_name[file_name_length] = 0; | 128 direntry.d_name[file_name_length] = 0; |
| 132 } | 129 } |
| 133 | 130 |
| 134 // Release the output buffer. | 131 // Release the output buffer. |
| 135 free(output_buf.data); | 132 free(output_buf.data); |
| 136 | 133 |
| 137 // Force size to a multiple of dirent | 134 // Force size to a multiple of dirent |
| 138 size -= size % sizeof(struct dirent); | 135 size -= size % sizeof(struct dirent); |
| 139 size_t max = dirents.size() * sizeof(struct dirent); | 136 size_t max = dirents.size() * sizeof(struct dirent); |
| 140 | 137 |
| 141 if (offs >= max) return 0; | 138 if (offs >= max) |
| 142 if (offs + size >= max) size = max - offs; | 139 return 0; |
| 140 |
| 141 if (offs + size >= max) |
| 142 size = max - offs; |
| 143 | 143 |
| 144 memcpy(pdir, reinterpret_cast<char*>(dirents.data()) + offs, size); | 144 memcpy(pdir, reinterpret_cast<char*>(dirents.data()) + offs, size); |
| 145 return 0; | 145 return 0; |
| 146 } | 146 } |
| 147 | 147 |
| 148 int MountNodeHtml5Fs::GetStat(struct stat* stat) { | 148 Error MountNodeHtml5Fs::GetStat(struct stat* stat) { |
| 149 AutoLock lock(&lock_); | 149 AutoLock lock(&lock_); |
| 150 | 150 |
| 151 PP_FileInfo info; | 151 PP_FileInfo info; |
| 152 int32_t result = mount_->ppapi()->GetFileIoInterface()->Query( | 152 int32_t result = mount_->ppapi()->GetFileIoInterface() |
| 153 fileio_resource_, &info, PP_BlockUntilComplete()); | 153 ->Query(fileio_resource_, &info, PP_BlockUntilComplete()); |
| 154 if (result != PP_OK) { | 154 if (result != PP_OK) |
| 155 errno = PPErrorToErrno(result); | 155 return PPErrorToErrno(result); |
| 156 return -1; | |
| 157 } | |
| 158 | 156 |
| 159 // Fill in known info here. | 157 // Fill in known info here. |
| 160 memcpy(stat, &stat_, sizeof(stat_)); | 158 memcpy(stat, &stat_, sizeof(stat_)); |
| 161 | 159 |
| 162 // Fill in the additional info from ppapi. | 160 // Fill in the additional info from ppapi. |
| 163 switch (info.type) { | 161 switch (info.type) { |
| 164 case PP_FILETYPE_REGULAR: stat->st_mode |= S_IFREG; break; | 162 case PP_FILETYPE_REGULAR: |
| 165 case PP_FILETYPE_DIRECTORY: stat->st_mode |= S_IFDIR; break; | 163 stat->st_mode |= S_IFREG; |
| 164 break; |
| 165 case PP_FILETYPE_DIRECTORY: |
| 166 stat->st_mode |= S_IFDIR; |
| 167 break; |
| 166 case PP_FILETYPE_OTHER: | 168 case PP_FILETYPE_OTHER: |
| 167 default: break; | 169 default: |
| 170 break; |
| 168 } | 171 } |
| 169 stat->st_size = static_cast<off_t>(info.size); | 172 stat->st_size = static_cast<off_t>(info.size); |
| 170 stat->st_atime = info.last_access_time; | 173 stat->st_atime = info.last_access_time; |
| 171 stat->st_mtime = info.last_modified_time; | 174 stat->st_mtime = info.last_modified_time; |
| 172 stat->st_ctime = info.creation_time; | 175 stat->st_ctime = info.creation_time; |
| 173 | 176 |
| 174 return 0; | 177 return 0; |
| 175 } | 178 } |
| 176 | 179 |
| 177 int MountNodeHtml5Fs::Read(size_t offs, void* buf, size_t count) { | 180 Error MountNodeHtml5Fs::Read(size_t offs, |
| 178 int32_t result = mount_->ppapi()->GetFileIoInterface()->Read( | 181 void* buf, |
| 179 fileio_resource_, offs, static_cast<char*>(buf), | 182 size_t count, |
| 180 static_cast<int32_t>(count), | 183 int* out_bytes) { |
| 181 PP_BlockUntilComplete()); | 184 *out_bytes = 0; |
| 182 if (result < 0) { | |
| 183 errno = PPErrorToErrno(result); | |
| 184 return -1; | |
| 185 } | |
| 186 | 185 |
| 187 return result; | 186 int32_t result = |
| 188 } | 187 mount_->ppapi()->GetFileIoInterface()->Read(fileio_resource_, |
| 188 offs, |
| 189 static_cast<char*>(buf), |
| 190 static_cast<int32_t>(count), |
| 191 PP_BlockUntilComplete()); |
| 192 if (result < 0) |
| 193 return PPErrorToErrno(result); |
| 189 | 194 |
| 190 int MountNodeHtml5Fs::FTruncate(off_t size) { | 195 *out_bytes = result; |
| 191 int32_t result = mount_->ppapi()->GetFileIoInterface()->SetLength( | |
| 192 fileio_resource_, size, PP_BlockUntilComplete()); | |
| 193 if (result != PP_OK) { | |
| 194 errno = PPErrorToErrno(result); | |
| 195 return -1; | |
| 196 } | |
| 197 | |
| 198 return 0; | 196 return 0; |
| 199 } | 197 } |
| 200 | 198 |
| 201 int MountNodeHtml5Fs::Write(size_t offs, const void* buf, size_t count) { | 199 Error MountNodeHtml5Fs::FTruncate(off_t size) { |
| 202 int32_t result = mount_->ppapi()->GetFileIoInterface()->Write( | 200 int32_t result = mount_->ppapi()->GetFileIoInterface() |
| 203 fileio_resource_, offs, static_cast<const char*>(buf), | 201 ->SetLength(fileio_resource_, size, PP_BlockUntilComplete()); |
| 204 static_cast<int32_t>(count), PP_BlockUntilComplete()); | 202 if (result != PP_OK) |
| 205 if (result < 0) { | 203 return PPErrorToErrno(result); |
| 206 errno = PPErrorToErrno(result); | 204 return 0; |
| 207 return -1; | |
| 208 } | |
| 209 | |
| 210 return result; | |
| 211 } | 205 } |
| 212 | 206 |
| 213 size_t MountNodeHtml5Fs::GetSize() { | 207 Error MountNodeHtml5Fs::Write(size_t offs, |
| 208 const void* buf, |
| 209 size_t count, |
| 210 int* out_bytes) { |
| 211 *out_bytes = 0; |
| 212 |
| 213 int32_t result = mount_->ppapi()->GetFileIoInterface() |
| 214 ->Write(fileio_resource_, |
| 215 offs, |
| 216 static_cast<const char*>(buf), |
| 217 static_cast<int32_t>(count), |
| 218 PP_BlockUntilComplete()); |
| 219 if (result < 0) |
| 220 return PPErrorToErrno(result); |
| 221 |
| 222 *out_bytes = result; |
| 223 return 0; |
| 224 } |
| 225 |
| 226 Error MountNodeHtml5Fs::GetSize(size_t* out_size) { |
| 227 *out_size = 0; |
| 228 |
| 214 AutoLock lock(&lock_); | 229 AutoLock lock(&lock_); |
| 215 | 230 |
| 216 PP_FileInfo info; | 231 PP_FileInfo info; |
| 217 int32_t result = mount_->ppapi()->GetFileIoInterface()->Query( | 232 int32_t result = mount_->ppapi()->GetFileIoInterface() |
| 218 fileio_resource_, &info, PP_BlockUntilComplete()); | 233 ->Query(fileio_resource_, &info, PP_BlockUntilComplete()); |
| 219 if (result != PP_OK) { | 234 if (result != PP_OK) |
| 220 errno = PPErrorToErrno(result); | 235 return PPErrorToErrno(result); |
| 221 return -1; | |
| 222 } | |
| 223 | 236 |
| 224 return static_cast<size_t>(info.size); | 237 *out_size = static_cast<size_t>(info.size); |
| 238 return 0; |
| 225 } | 239 } |
| 226 | 240 |
| 227 MountNodeHtml5Fs::MountNodeHtml5Fs(Mount* mount, PP_Resource fileref_resource) | 241 MountNodeHtml5Fs::MountNodeHtml5Fs(Mount* mount, PP_Resource fileref_resource) |
| 228 : MountNode(mount), | 242 : MountNode(mount), |
| 229 fileref_resource_(fileref_resource), | 243 fileref_resource_(fileref_resource), |
| 230 fileio_resource_(0) { | 244 fileio_resource_(0) {} |
| 231 } | |
| 232 | 245 |
| 233 bool MountNodeHtml5Fs::Init(int perm) { | 246 Error MountNodeHtml5Fs::Init(int perm) { |
| 234 if (!MountNode::Init(Mount::OpenModeToPermission(perm))) | 247 Error error = MountNode::Init(Mount::OpenModeToPermission(perm)); |
| 235 return false; | 248 if (error) |
| 249 return error; |
| 236 | 250 |
| 237 fileio_resource_= mount_->ppapi()->GetFileIoInterface()->Create( | 251 fileio_resource_ = mount_->ppapi()->GetFileIoInterface() |
| 238 mount_->ppapi()->GetInstance()); | 252 ->Create(mount_->ppapi()->GetInstance()); |
| 239 if (!fileio_resource_) | 253 if (!fileio_resource_) |
| 240 return false; | 254 return ENOSYS; |
| 241 | 255 |
| 242 int32_t open_result = mount_->ppapi()->GetFileIoInterface()->Open( | 256 int32_t open_result = |
| 243 fileio_resource_, fileref_resource_, ModeToOpenFlags(perm), | 257 mount_->ppapi()->GetFileIoInterface()->Open(fileio_resource_, |
| 244 PP_BlockUntilComplete()); | 258 fileref_resource_, |
| 259 ModeToOpenFlags(perm), |
| 260 PP_BlockUntilComplete()); |
| 245 if (open_result != PP_OK) | 261 if (open_result != PP_OK) |
| 246 return false; | 262 return PPErrorToErrno(open_result); |
| 247 | 263 return 0; |
| 248 return true; | |
| 249 } | 264 } |
| 250 | 265 |
| 251 void MountNodeHtml5Fs::Destroy() { | 266 void MountNodeHtml5Fs::Destroy() { |
| 252 FSync(); | 267 FSync(); |
| 253 | 268 |
| 254 if (fileio_resource_) { | 269 if (fileio_resource_) { |
| 255 mount_->ppapi()->GetFileIoInterface()->Close(fileio_resource_); | 270 mount_->ppapi()->GetFileIoInterface()->Close(fileio_resource_); |
| 256 mount_->ppapi()->ReleaseResource(fileio_resource_); | 271 mount_->ppapi()->ReleaseResource(fileio_resource_); |
| 257 } | 272 } |
| 258 | 273 |
| 259 mount_->ppapi()->ReleaseResource(fileref_resource_); | 274 mount_->ppapi()->ReleaseResource(fileref_resource_); |
| 260 fileio_resource_ = 0; | 275 fileio_resource_ = 0; |
| 261 fileref_resource_ = 0; | 276 fileref_resource_ = 0; |
| 262 MountNode::Destroy(); | 277 MountNode::Destroy(); |
| 263 } | 278 } |
| OLD | NEW |