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 24 matching lines...) Expand all Loading... |
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 = ppapi()->GetFileRefInterface()->Create( |
45 filesystem_resource_, 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; |
55 return 0; | 55 return 0; |
56 } | 56 } |
57 | 57 |
| 58 Path Html5Fs::GetFullPath(const Path& path) { |
| 59 Path full_path(path); |
| 60 full_path.Prepend(prefix_); |
| 61 return full_path; |
| 62 } |
| 63 |
58 Error Html5Fs::Unlink(const Path& path) { | 64 Error Html5Fs::Unlink(const Path& path) { |
59 return Remove(path); | 65 return RemoveInternal(path, REMOVE_FILE); |
60 } | 66 } |
61 | 67 |
62 Error Html5Fs::Mkdir(const Path& path, int permissions) { | 68 Error Html5Fs::Mkdir(const Path& path, int permissions) { |
63 Error error = BlockUntilFilesystemOpen(); | 69 Error error = BlockUntilFilesystemOpen(); |
64 if (error) | 70 if (error) |
65 return error; | 71 return error; |
66 | 72 |
67 // 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 |
68 // 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. |
69 if (path.IsRoot()) | 75 if (path.IsRoot()) |
70 return EEXIST; | 76 return EEXIST; |
71 | 77 |
72 ScopedResource fileref_resource( | 78 ScopedResource fileref_resource( |
73 ppapi(), | 79 ppapi(), |
74 ppapi()->GetFileRefInterface()->Create(filesystem_resource_, | 80 ppapi()->GetFileRefInterface()->Create(filesystem_resource_, |
75 path.Join().c_str())); | 81 GetFullPath(path).Join().c_str())); |
76 if (!fileref_resource.pp_resource()) | 82 if (!fileref_resource.pp_resource()) |
77 return ENOENT; | 83 return ENOENT; |
78 | 84 |
79 int32_t result = ppapi()->GetFileRefInterface()->MakeDirectory( | 85 int32_t result = ppapi()->GetFileRefInterface()->MakeDirectory( |
80 fileref_resource.pp_resource(), PP_FALSE, PP_BlockUntilComplete()); | 86 fileref_resource.pp_resource(), PP_FALSE, PP_BlockUntilComplete()); |
81 if (result != PP_OK) | 87 if (result != PP_OK) |
82 return PPErrorToErrno(result); | 88 return PPErrorToErrno(result); |
83 | 89 |
84 return 0; | 90 return 0; |
85 } | 91 } |
86 | 92 |
87 Error Html5Fs::Rmdir(const Path& path) { | 93 Error Html5Fs::Rmdir(const Path& path) { |
88 return Remove(path); | 94 return RemoveInternal(path, REMOVE_DIR); |
89 } | 95 } |
90 | 96 |
91 Error Html5Fs::Remove(const Path& path) { | 97 Error Html5Fs::Remove(const Path& path) { |
| 98 return RemoveInternal(path, REMOVE_ALL); |
| 99 } |
| 100 |
| 101 Error Html5Fs::RemoveInternal(const Path& path, int remove_type) { |
92 Error error = BlockUntilFilesystemOpen(); | 102 Error error = BlockUntilFilesystemOpen(); |
93 if (error) | 103 if (error) |
94 return error; | 104 return error; |
95 | 105 |
96 ScopedResource fileref_resource( | 106 ScopedResource fileref_resource( |
97 ppapi(), | 107 ppapi(), |
98 ppapi()->GetFileRefInterface()->Create(filesystem_resource_, | 108 ppapi()->GetFileRefInterface()->Create(filesystem_resource_, |
99 path.Join().c_str())); | 109 GetFullPath(path).Join().c_str())); |
100 if (!fileref_resource.pp_resource()) | 110 if (!fileref_resource.pp_resource()) |
101 return ENOENT; | 111 return ENOENT; |
102 | 112 |
| 113 // Check file type |
| 114 if (remove_type != REMOVE_ALL) { |
| 115 PP_FileInfo file_info; |
| 116 int32_t query_result = ppapi()->GetFileRefInterface()->Query( |
| 117 fileref_resource.pp_resource(), &file_info, PP_BlockUntilComplete()); |
| 118 if (query_result != PP_OK) { |
| 119 LOG_ERROR("Error querying file type"); |
| 120 return EINVAL; |
| 121 } |
| 122 switch (file_info.type) { |
| 123 case PP_FILETYPE_DIRECTORY: |
| 124 if (!(remove_type & REMOVE_DIR)) |
| 125 return EISDIR; |
| 126 break; |
| 127 case PP_FILETYPE_REGULAR: |
| 128 if (!(remove_type & REMOVE_FILE)) |
| 129 return ENOTDIR; |
| 130 break; |
| 131 default: |
| 132 LOG_ERROR("Invalid file type: %d", file_info.type); |
| 133 return EINVAL; |
| 134 } |
| 135 } |
| 136 |
103 int32_t result = ppapi()->GetFileRefInterface()->Delete( | 137 int32_t result = ppapi()->GetFileRefInterface()->Delete( |
104 fileref_resource.pp_resource(), PP_BlockUntilComplete()); | 138 fileref_resource.pp_resource(), PP_BlockUntilComplete()); |
105 if (result != PP_OK) | 139 if (result != PP_OK) |
106 return PPErrorToErrno(result); | 140 return PPErrorToErrno(result); |
107 | 141 |
108 return 0; | 142 return 0; |
109 } | 143 } |
110 | 144 |
111 Error Html5Fs::Rename(const Path& path, const Path& newpath) { | 145 Error Html5Fs::Rename(const Path& path, const Path& newpath) { |
112 Error error = BlockUntilFilesystemOpen(); | 146 Error error = BlockUntilFilesystemOpen(); |
113 if (error) | 147 if (error) |
114 return error; | 148 return error; |
115 | 149 |
| 150 const char* oldpath_full = GetFullPath(path).Join().c_str(); |
116 ScopedResource fileref_resource( | 151 ScopedResource fileref_resource( |
117 ppapi(), | 152 ppapi(), |
118 ppapi()->GetFileRefInterface()->Create(filesystem_resource_, | 153 ppapi()->GetFileRefInterface()->Create(filesystem_resource_, |
119 path.Join().c_str())); | 154 oldpath_full)); |
120 if (!fileref_resource.pp_resource()) | 155 if (!fileref_resource.pp_resource()) |
121 return ENOENT; | 156 return ENOENT; |
122 | 157 |
| 158 const char* newpath_full = GetFullPath(newpath).Join().c_str(); |
123 ScopedResource new_fileref_resource( | 159 ScopedResource new_fileref_resource( |
124 ppapi(), | 160 ppapi(), |
125 ppapi()->GetFileRefInterface()->Create(filesystem_resource_, | 161 ppapi()->GetFileRefInterface()->Create(filesystem_resource_, |
126 newpath.Join().c_str())); | 162 newpath_full)); |
127 if (!new_fileref_resource.pp_resource()) | 163 if (!new_fileref_resource.pp_resource()) |
128 return ENOENT; | 164 return ENOENT; |
129 | 165 |
130 int32_t result = | 166 int32_t result = |
131 ppapi()->GetFileRefInterface()->Rename(fileref_resource.pp_resource(), | 167 ppapi()->GetFileRefInterface()->Rename(fileref_resource.pp_resource(), |
132 new_fileref_resource.pp_resource(), | 168 new_fileref_resource.pp_resource(), |
133 PP_BlockUntilComplete()); | 169 PP_BlockUntilComplete()); |
134 if (result != PP_OK) | 170 if (result != PP_OK) |
135 return PPErrorToErrno(result); | 171 return PPErrorToErrno(result); |
136 | 172 |
(...skipping 20 matching lines...) Expand all Loading... |
157 PP_FileSystemType filesystem_type = PP_FILESYSTEMTYPE_LOCALPERSISTENT; | 193 PP_FileSystemType filesystem_type = PP_FILESYSTEMTYPE_LOCALPERSISTENT; |
158 int64_t expected_size = 0; | 194 int64_t expected_size = 0; |
159 for (StringMap_t::const_iterator iter = args.string_map.begin(); | 195 for (StringMap_t::const_iterator iter = args.string_map.begin(); |
160 iter != args.string_map.end(); | 196 iter != args.string_map.end(); |
161 ++iter) { | 197 ++iter) { |
162 if (iter->first == "type") { | 198 if (iter->first == "type") { |
163 if (iter->second == "PERSISTENT") { | 199 if (iter->second == "PERSISTENT") { |
164 filesystem_type = PP_FILESYSTEMTYPE_LOCALPERSISTENT; | 200 filesystem_type = PP_FILESYSTEMTYPE_LOCALPERSISTENT; |
165 } else if (iter->second == "TEMPORARY") { | 201 } else if (iter->second == "TEMPORARY") { |
166 filesystem_type = PP_FILESYSTEMTYPE_LOCALTEMPORARY; | 202 filesystem_type = PP_FILESYSTEMTYPE_LOCALTEMPORARY; |
| 203 } else if (iter->second == "") { |
| 204 filesystem_type = PP_FILESYSTEMTYPE_LOCALPERSISTENT; |
| 205 } else { |
| 206 LOG_ERROR("html5fs: unknown type: '%s'", iter->second.c_str()); |
| 207 return EINVAL; |
167 } | 208 } |
168 } else if (iter->first == "expected_size") { | 209 } else if (iter->first == "expected_size") { |
169 expected_size = strtoull(iter->second.c_str(), NULL, 10); | 210 expected_size = strtoull(iter->second.c_str(), NULL, 10); |
170 } else if (iter->first == "filesystem_resource") { | 211 } else if (iter->first == "filesystem_resource") { |
171 PP_Resource resource = strtoull(iter->second.c_str(), NULL, 10); | 212 PP_Resource resource = strtoull(iter->second.c_str(), NULL, 10); |
172 if (!ppapi_->GetFileSystemInterface()->IsFileSystem(resource)) | 213 if (!ppapi_->GetFileSystemInterface()->IsFileSystem(resource)) |
173 return EINVAL; | 214 return EINVAL; |
174 | 215 |
175 filesystem_resource_ = resource; | 216 filesystem_resource_ = resource; |
176 ppapi_->AddRefResource(filesystem_resource_); | 217 ppapi_->AddRefResource(filesystem_resource_); |
| 218 } else if (iter->first == "SOURCE") { |
| 219 prefix_ = iter->second; |
| 220 } else { |
| 221 LOG_ERROR("html5fs: bad param: %s", iter->first.c_str()); |
| 222 return EINVAL; |
177 } | 223 } |
178 } | 224 } |
179 | 225 |
180 if (filesystem_resource_ != 0) { | 226 if (filesystem_resource_ != 0) { |
181 filesystem_open_has_result_ = true; | 227 filesystem_open_has_result_ = true; |
182 filesystem_open_error_ = PP_OK; | 228 filesystem_open_error_ = PP_OK; |
183 return 0; | 229 return 0; |
184 } | 230 } |
185 | 231 |
186 // Initialize filesystem. | 232 // Initialize filesystem. |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
233 } | 279 } |
234 | 280 |
235 void Html5Fs::FilesystemOpenCallback(int32_t result) { | 281 void Html5Fs::FilesystemOpenCallback(int32_t result) { |
236 AUTO_LOCK(filesysem_open_lock_); | 282 AUTO_LOCK(filesysem_open_lock_); |
237 filesystem_open_has_result_ = true; | 283 filesystem_open_has_result_ = true; |
238 filesystem_open_error_ = PPErrorToErrno(result); | 284 filesystem_open_error_ = PPErrorToErrno(result); |
239 pthread_cond_signal(&filesystem_open_cond_); | 285 pthread_cond_signal(&filesystem_open_cond_); |
240 } | 286 } |
241 | 287 |
242 } // namespace nacl_io | 288 } // namespace nacl_io |
OLD | NEW |