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 |