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 #include "nacl_io/kernel_proxy.h" | 5 #include "nacl_io/kernel_proxy.h" |
6 | 6 |
7 #include <assert.h> | 7 #include <assert.h> |
8 #include <errno.h> | 8 #include <errno.h> |
9 #include <fcntl.h> | 9 #include <fcntl.h> |
10 #include <pthread.h> | 10 #include <pthread.h> |
(...skipping 18 matching lines...) Expand all Loading... | |
29 #include "utils/ref_object.h" | 29 #include "utils/ref_object.h" |
30 | 30 |
31 #ifndef MAXPATHLEN | 31 #ifndef MAXPATHLEN |
32 #define MAXPATHLEN 256 | 32 #define MAXPATHLEN 256 |
33 #endif | 33 #endif |
34 | 34 |
35 // TODO(noelallen) : Grab/Redefine these in the kernel object once available. | 35 // TODO(noelallen) : Grab/Redefine these in the kernel object once available. |
36 #define USR_ID 1002 | 36 #define USR_ID 1002 |
37 #define GRP_ID 1003 | 37 #define GRP_ID 1003 |
38 | 38 |
39 KernelProxy::KernelProxy() : dev_(0), ppapi_(NULL) {} | |
39 | 40 |
40 | 41 KernelProxy::~KernelProxy() { delete ppapi_; } |
41 KernelProxy::KernelProxy() | |
42 : dev_(0), | |
43 ppapi_(NULL) { | |
44 } | |
45 | |
46 KernelProxy::~KernelProxy() { | |
47 delete ppapi_; | |
48 } | |
49 | 42 |
50 void KernelProxy::Init(PepperInterface* ppapi) { | 43 void KernelProxy::Init(PepperInterface* ppapi) { |
51 ppapi_ = ppapi; | 44 ppapi_ = ppapi; |
52 cwd_ = "/"; | 45 cwd_ = "/"; |
53 dev_ = 1; | 46 dev_ = 1; |
54 | 47 |
55 factories_["memfs"] = MountMem::Create<MountMem>; | 48 factories_["memfs"] = MountMem::Create<MountMem>; |
56 factories_["dev"] = MountDev::Create<MountDev>; | 49 factories_["dev"] = MountDev::Create<MountDev>; |
57 factories_["html5fs"] = MountHtml5Fs::Create<MountHtml5Fs>; | 50 factories_["html5fs"] = MountHtml5Fs::Create<MountHtml5Fs>; |
58 factories_["httpfs"] = MountHttp::Create<MountHttp>; | 51 factories_["httpfs"] = MountHttp::Create<MountHttp>; |
59 factories_["passthroughfs"] = MountPassthrough::Create<MountPassthrough>; | 52 factories_["passthroughfs"] = MountPassthrough::Create<MountPassthrough>; |
60 | 53 |
61 // Create passthrough mount at root | 54 int result; |
62 StringMap_t smap; | 55 result = mount("", "/", "passthroughfs", 0, NULL); |
63 mounts_["/"] = MountPassthrough::Create<MountPassthrough>( | 56 assert(result == 0); |
64 dev_++, smap, ppapi_); | 57 |
65 mounts_["/dev"] = MountDev::Create<MountDev>(dev_++, smap, ppapi_); | 58 result = mount("", "/dev", "dev", 0, NULL); |
59 assert(result == 0); | |
66 | 60 |
67 // Open the first three in order to get STDIN, STDOUT, STDERR | 61 // Open the first three in order to get STDIN, STDOUT, STDERR |
68 open("/dev/stdin", O_RDONLY); | 62 open("/dev/stdin", O_RDONLY); |
69 open("/dev/stdout", O_WRONLY); | 63 open("/dev/stdout", O_WRONLY); |
70 open("/dev/stderr", O_WRONLY); | 64 open("/dev/stderr", O_WRONLY); |
71 } | 65 } |
72 | 66 |
73 int KernelProxy::open(const char *path, int oflags) { | 67 int KernelProxy::open(const char* path, int oflags) { |
noelallen1
2013/06/07 21:48:43
Error KernelProxy::open?
binji
2013/06/07 23:23:11
No, KernelProxy mimicks the actual open call, so i
| |
74 Path rel; | 68 Path rel; |
75 | 69 |
76 Mount* mnt = AcquireMountAndPath(path, &rel); | 70 Mount* mnt; |
77 if (mnt == NULL) return -1; | 71 Error error = AcquireMountAndPath(path, &mnt, &rel); |
72 if (error) { | |
73 errno = error; | |
74 return -1; | |
75 } | |
78 | 76 |
79 MountNode* node = mnt->Open(rel, oflags); | 77 MountNode* node = NULL; |
80 if (node == NULL) { | 78 error = mnt->Open(rel, oflags, &node); |
79 if (error) { | |
80 errno = error; | |
81 ReleaseMount(mnt); | 81 ReleaseMount(mnt); |
82 return -1; | 82 return -1; |
83 } | 83 } |
84 | 84 |
85 KernelHandle* handle = new KernelHandle(mnt, node, oflags); | 85 KernelHandle* handle = new KernelHandle(mnt, node); |
86 error = handle->Init(oflags); | |
87 if (error) { | |
88 errno = error; | |
89 ReleaseMount(mnt); | |
90 return -1; | |
91 } | |
92 | |
86 int fd = AllocateFD(handle); | 93 int fd = AllocateFD(handle); |
87 mnt->AcquireNode(node); | 94 mnt->AcquireNode(node); |
88 | 95 |
89 ReleaseHandle(handle); | 96 ReleaseHandle(handle); |
90 ReleaseMount(mnt); | 97 ReleaseMount(mnt); |
91 | 98 |
92 return fd; | 99 return fd; |
93 } | 100 } |
94 | 101 |
95 int KernelProxy::close(int fd) { | 102 int KernelProxy::close(int fd) { |
noelallen1
2013/06/07 21:48:43
Error KernelProxy::close?
| |
96 KernelHandle* handle = AcquireHandle(fd); | 103 KernelHandle* handle; |
97 | 104 Error error = AcquireHandle(fd, &handle); |
98 if (NULL == handle) return -1; | 105 if (error) { |
106 errno = error; | |
noelallen1
2013/06/07 21:48:43
Should a non EOK set errno, so that we don't need
| |
107 return -1; | |
108 } | |
99 | 109 |
100 Mount* mount = handle->mount_; | 110 Mount* mount = handle->mount_; |
101 // Acquire the mount to ensure FreeFD doesn't prematurely destroy it. | 111 // Acquire the mount to ensure FreeFD doesn't prematurely destroy it. |
102 mount->Acquire(); | 112 mount->Acquire(); |
103 | 113 |
104 // FreeFD will release the handle/mount held by this fd. | 114 // FreeFD will release the handle/mount held by this fd. |
105 FreeFD(fd); | 115 FreeFD(fd); |
106 | 116 |
107 // If this handle is the last reference to its node, releasing it will close | 117 // If this handle is the last reference to its node, releasing it will close |
108 // the node. | 118 // the node. |
109 ReleaseHandle(handle); | 119 ReleaseHandle(handle); |
110 | 120 |
111 // Finally, release the mount. | 121 // Finally, release the mount. |
112 mount->Release(); | 122 mount->Release(); |
113 | 123 |
114 return 0; | 124 return 0; |
115 } | 125 } |
116 | 126 |
117 int KernelProxy::dup(int oldfd) { | 127 int KernelProxy::dup(int oldfd) { |
noelallen1
2013/06/07 21:48:43
Same and below.
| |
118 KernelHandle* handle = AcquireHandle(oldfd); | 128 KernelHandle* handle; |
119 if (NULL == handle) return -1; | 129 Error error = AcquireHandle(oldfd, &handle); |
130 if (error) { | |
131 errno = error; | |
132 return -1; | |
133 } | |
120 | 134 |
121 int newfd = AllocateFD(handle); | 135 int newfd = AllocateFD(handle); |
122 ReleaseHandle(handle); | 136 ReleaseHandle(handle); |
123 | 137 |
124 return newfd; | 138 return newfd; |
125 } | 139 } |
126 | 140 |
127 int KernelProxy::dup2(int oldfd, int newfd) { | 141 int KernelProxy::dup2(int oldfd, int newfd) { |
128 // If it's the same file handle, just return | 142 // If it's the same file handle, just return |
129 if (oldfd == newfd) return newfd; | 143 if (oldfd == newfd) |
144 return newfd; | |
130 | 145 |
131 KernelHandle* old_handle = AcquireHandle(oldfd); | 146 KernelHandle* old_handle; |
132 if (NULL == old_handle) return -1; | 147 Error error = AcquireHandle(oldfd, &old_handle); |
148 if (error) { | |
149 errno = error; | |
150 return -1; | |
151 } | |
133 | 152 |
134 FreeAndReassignFD(newfd, old_handle); | 153 FreeAndReassignFD(newfd, old_handle); |
135 ReleaseHandle(old_handle); | 154 ReleaseHandle(old_handle); |
136 return newfd; | 155 return newfd; |
137 } | 156 } |
138 | 157 |
139 | |
140 char* KernelProxy::getcwd(char* buf, size_t size) { | 158 char* KernelProxy::getcwd(char* buf, size_t size) { |
141 AutoLock lock(&process_lock_); | 159 AutoLock lock(&process_lock_); |
142 if (size <= 0) { | 160 if (size <= 0) { |
143 errno = EINVAL; | 161 errno = EINVAL; |
144 return NULL; | 162 return NULL; |
145 } | 163 } |
146 // If size is 0, allocate as much as we need. | 164 // If size is 0, allocate as much as we need. |
147 if (size == 0) { | 165 if (size == 0) { |
148 size = cwd_.size() + 1; | 166 size = cwd_.size() + 1; |
149 } | 167 } |
(...skipping 14 matching lines...) Expand all Loading... | |
164 } | 182 } |
165 | 183 |
166 char* KernelProxy::getwd(char* buf) { | 184 char* KernelProxy::getwd(char* buf) { |
167 if (NULL == buf) { | 185 if (NULL == buf) { |
168 errno = EFAULT; | 186 errno = EFAULT; |
169 return NULL; | 187 return NULL; |
170 } | 188 } |
171 return getcwd(buf, MAXPATHLEN); | 189 return getcwd(buf, MAXPATHLEN); |
172 } | 190 } |
173 | 191 |
174 int KernelProxy::chmod(const char *path, mode_t mode) { | 192 int KernelProxy::chmod(const char* path, mode_t mode) { |
175 int fd = KernelProxy::open(path, O_RDWR); | 193 int fd = KernelProxy::open(path, O_RDWR); |
176 if (-1 == fd) return -1; | 194 if (-1 == fd) |
195 return -1; | |
177 | 196 |
178 int ret = fchmod(fd, mode); | 197 int result = fchmod(fd, mode); |
179 close(fd); | 198 close(fd); |
180 return ret; | 199 return result; |
181 } | 200 } |
182 | 201 |
183 int KernelProxy::mkdir(const char *path, mode_t mode) { | 202 int KernelProxy::mkdir(const char* path, mode_t mode) { |
203 Mount* mnt; | |
184 Path rel; | 204 Path rel; |
185 Mount* mnt = AcquireMountAndPath(path, &rel); | 205 Error error = AcquireMountAndPath(path, &mnt, &rel); |
186 if (mnt == NULL) return -1; | 206 if (error) { |
207 errno = error; | |
208 return -1; | |
209 } | |
187 | 210 |
188 int val = mnt->Mkdir(rel, mode); | 211 int result = 0; |
212 error = mnt->Mkdir(rel, mode); | |
213 if (error) { | |
214 errno = error; | |
215 result = -1; | |
216 } | |
217 | |
189 ReleaseMount(mnt); | 218 ReleaseMount(mnt); |
190 return val; | 219 return result; |
191 } | 220 } |
192 | 221 |
193 int KernelProxy::rmdir(const char *path) { | 222 int KernelProxy::rmdir(const char* path) { |
223 Mount* mnt; | |
194 Path rel; | 224 Path rel; |
195 Mount* mnt = AcquireMountAndPath(path, &rel); | 225 Error error = AcquireMountAndPath(path, &mnt, &rel); |
196 if (mnt == NULL) return -1; | 226 if (error) { |
227 errno = error; | |
228 return -1; | |
229 } | |
197 | 230 |
198 int val = mnt->Rmdir(rel); | 231 int result = 0; |
232 error = mnt->Rmdir(rel); | |
233 if (error) { | |
234 errno = error; | |
235 result = -1; | |
236 } | |
237 | |
199 ReleaseMount(mnt); | 238 ReleaseMount(mnt); |
200 return val; | 239 return result; |
201 } | 240 } |
202 | 241 |
203 int KernelProxy::stat(const char *path, struct stat *buf) { | 242 int KernelProxy::stat(const char* path, struct stat* buf) { |
204 int fd = open(path, O_RDONLY); | 243 int fd = open(path, O_RDONLY); |
205 if (-1 == fd) return -1; | 244 if (-1 == fd) |
245 return -1; | |
206 | 246 |
207 int ret = fstat(fd, buf); | 247 int result = fstat(fd, buf); |
208 close(fd); | 248 close(fd); |
209 return ret; | 249 return result; |
210 } | 250 } |
211 | 251 |
212 int KernelProxy::chdir(const char* path) { | 252 int KernelProxy::chdir(const char* path) { |
213 struct stat statbuf; | 253 struct stat statbuf; |
214 if (stat(path, &statbuf) == -1) | 254 if (stat(path, &statbuf) == -1) |
215 return -1; | 255 return -1; |
216 | 256 |
217 bool is_dir = (statbuf.st_mode & S_IFDIR) != 0; | 257 bool is_dir = (statbuf.st_mode & S_IFDIR) != 0; |
218 if (is_dir) { | 258 if (!is_dir) { |
219 AutoLock lock(&process_lock_); | 259 errno = ENOTDIR; |
220 cwd_ = GetAbsPathLocked(path).Join(); | 260 return -1; |
221 return 0; | |
222 } | 261 } |
223 | 262 |
224 errno = ENOTDIR; | 263 AutoLock lock(&process_lock_); |
225 return -1; | 264 cwd_ = GetAbsPathLocked(path).Join(); |
265 return 0; | |
226 } | 266 } |
227 | 267 |
228 int KernelProxy::mount(const char *source, const char *target, | 268 int KernelProxy::mount(const char* source, |
229 const char *filesystemtype, unsigned long mountflags, | 269 const char* target, |
230 const void *data) { | 270 const char* filesystemtype, |
271 unsigned long mountflags, | |
272 const void* data) { | |
231 // See if it's already mounted | 273 // See if it's already mounted |
232 std::string abs_targ; | 274 std::string abs_targ; |
233 | 275 |
234 // Scope this lock to prevent holding both process and kernel locks | 276 // Scope this lock to prevent holding both process and kernel locks |
235 { | 277 { |
236 AutoLock lock(&process_lock_); | 278 AutoLock lock(&process_lock_); |
237 abs_targ = GetAbsPathLocked(target).Join(); | 279 abs_targ = GetAbsPathLocked(target).Join(); |
238 } | 280 } |
239 | 281 |
240 AutoLock lock(&kernel_lock_); | 282 AutoLock lock(&kernel_lock_); |
241 if (mounts_.find(abs_targ) != mounts_.end()) { | 283 if (mounts_.find(abs_targ) != mounts_.end()) { |
242 errno = EBUSY; | 284 errno = EBUSY; |
noelallen1
2013/06/07 21:48:43
Error(EBUSY) first?
| |
243 return -1; | 285 return -1; |
244 } | 286 } |
245 | 287 |
246 // Find a factory of that type | 288 // Find a factory of that type |
247 MountFactoryMap_t::iterator factory = factories_.find(filesystemtype); | 289 MountFactoryMap_t::iterator factory = factories_.find(filesystemtype); |
248 if (factory == factories_.end()) { | 290 if (factory == factories_.end()) { |
249 errno = ENODEV; | 291 errno = ENODEV; |
250 return -1; | 292 return -1; |
251 } | 293 } |
252 | 294 |
253 StringMap_t smap; | 295 StringMap_t smap; |
254 smap["SOURCE"] = source; | 296 smap["SOURCE"] = source; |
255 smap["TARGET"] = abs_targ; | 297 smap["TARGET"] = abs_targ; |
256 | 298 |
257 if (data) { | 299 if (data) { |
258 char* str = strdup(static_cast<const char *>(data)); | 300 char* str = strdup(static_cast<const char*>(data)); |
259 char* ptr = strtok(str,","); | 301 char* ptr = strtok(str, ","); |
260 char* val; | 302 char* val; |
261 while (ptr != NULL) { | 303 while (ptr != NULL) { |
262 val = strchr(ptr, '='); | 304 val = strchr(ptr, '='); |
263 if (val) { | 305 if (val) { |
264 *val = 0; | 306 *val = 0; |
265 smap[ptr] = val + 1; | 307 smap[ptr] = val + 1; |
266 } else { | 308 } else { |
267 smap[ptr] = "TRUE"; | 309 smap[ptr] = "TRUE"; |
268 } | 310 } |
269 ptr = strtok(NULL, ","); | 311 ptr = strtok(NULL, ","); |
270 } | 312 } |
271 free(str); | 313 free(str); |
272 } | 314 } |
273 | 315 |
274 Mount* mnt = factory->second(dev_++, smap, ppapi_); | 316 Mount* mnt = NULL; |
275 if (mnt) { | 317 Error error = factory->second(dev_++, smap, ppapi_, &mnt); |
276 mounts_[abs_targ] = mnt; | 318 if (error) { |
277 return 0; | 319 errno = error; |
320 return -1; | |
278 } | 321 } |
Sam Clegg
2013/05/31 18:40:29
Repetition like this makes me want to use a HANDLE
binji
2013/06/03 17:16:46
Agreed, though the if logic depends on what needs
noelallen1
2013/06/07 21:48:43
You mean?
#define CHECK_ERRNO_RETURN(r, expr)
{
binji
2013/06/07 23:23:11
Yes.
| |
279 errno = EINVAL; | 322 |
280 return -1; | 323 mounts_[abs_targ] = mnt; |
324 return 0; | |
281 } | 325 } |
282 | 326 |
283 int KernelProxy::umount(const char *path) { | 327 int KernelProxy::umount(const char* path) { |
284 Path abs_path; | 328 Path abs_path; |
285 | 329 |
286 // Scope this lock to prevent holding both process and kernel locks | 330 // Scope this lock to prevent holding both process and kernel locks |
287 { | 331 { |
288 AutoLock lock(&process_lock_); | 332 AutoLock lock(&process_lock_); |
289 abs_path = GetAbsPathLocked(path); | 333 abs_path = GetAbsPathLocked(path); |
290 } | 334 } |
291 | 335 |
292 AutoLock lock(&kernel_lock_); | 336 AutoLock lock(&kernel_lock_); |
293 MountMap_t::iterator it = mounts_.find(abs_path.Join()); | 337 MountMap_t::iterator it = mounts_.find(abs_path.Join()); |
294 | 338 |
295 if (mounts_.end() == it) { | 339 if (mounts_.end() == it) { |
296 errno = EINVAL; | 340 errno = EINVAL; |
noelallen1
2013/06/07 21:48:43
Error(EINVAL)? Same below.
| |
297 return -1; | 341 return -1; |
298 } | 342 } |
299 | 343 |
300 if (it->second->RefCount() != 1) { | 344 if (it->second->RefCount() != 1) { |
301 errno = EBUSY; | 345 errno = EBUSY; |
302 return -1; | 346 return -1; |
303 } | 347 } |
304 | 348 |
305 it->second->Release(); | 349 it->second->Release(); |
306 mounts_.erase(it); | 350 mounts_.erase(it); |
307 return 0; | 351 return 0; |
308 } | 352 } |
309 | 353 |
310 ssize_t KernelProxy::read(int fd, void *buf, size_t nbytes) { | 354 ssize_t KernelProxy::read(int fd, void* buf, size_t nbytes) { |
311 KernelHandle* handle = AcquireHandle(fd); | 355 KernelHandle* handle; |
312 | 356 Error error = AcquireHandle(fd, &handle); |
313 // check if fd is valid and handle exists | 357 if (error) { |
314 if (NULL == handle) return -1; | 358 errno = error; |
315 | 359 return -1; |
316 AutoLock lock(&handle->lock_); | 360 } |
317 ssize_t cnt = handle->node_->Read(handle->offs_, buf, nbytes); | 361 |
318 if (cnt > 0) handle->offs_ += cnt; | 362 AutoLock lock(&handle->lock_); |
363 ssize_t cnt = 0; | |
364 error = handle->node_->Read(handle->offs_, buf, nbytes, &cnt); | |
365 if (error) | |
366 errno = error; | |
367 | |
368 if (cnt > 0) | |
369 handle->offs_ += cnt; | |
319 | 370 |
320 ReleaseHandle(handle); | 371 ReleaseHandle(handle); |
321 return cnt; | 372 return cnt; |
322 } | 373 } |
323 | 374 |
324 ssize_t KernelProxy::write(int fd, const void *buf, size_t nbytes) { | 375 ssize_t KernelProxy::write(int fd, const void* buf, size_t nbytes) { |
325 KernelHandle* handle = AcquireHandle(fd); | 376 KernelHandle* handle; |
326 | 377 Error error = AcquireHandle(fd, &handle); |
327 // check if fd is valid and handle exists | 378 if (error) { |
328 if (NULL == handle) return -1; | 379 errno = error; |
329 | 380 return -1; |
330 AutoLock lock(&handle->lock_); | 381 } |
331 ssize_t cnt = handle->node_->Write(handle->offs_, buf, nbytes); | 382 |
332 if (cnt > 0) handle->offs_ += cnt; | 383 AutoLock lock(&handle->lock_); |
384 ssize_t cnt = 0; | |
385 error = handle->node_->Write(handle->offs_, buf, nbytes, &cnt); | |
386 if (error) | |
387 errno = error; | |
388 | |
389 if (cnt > 0) | |
390 handle->offs_ += cnt; | |
333 | 391 |
334 ReleaseHandle(handle); | 392 ReleaseHandle(handle); |
335 return cnt; | 393 return cnt; |
336 } | 394 } |
337 | 395 |
338 int KernelProxy::fstat(int fd, struct stat* buf) { | 396 int KernelProxy::fstat(int fd, struct stat* buf) { |
339 KernelHandle* handle = AcquireHandle(fd); | 397 KernelHandle* handle; |
noelallen1
2013/06/07 21:48:43
ScopedHandle handle;
CHECK_ERRNO_RET(-1, Acquir
binji
2013/06/07 23:23:11
Yep, future CL. :)
| |
340 | 398 Error error = AcquireHandle(fd, &handle); |
341 // check if fd is valid and handle exists | 399 if (error) { |
342 if (NULL == handle) return -1; | 400 errno = error; |
343 | 401 return -1; |
344 int ret = handle->node_->GetStat(buf); | 402 } |
345 ReleaseHandle(handle); | 403 |
346 return ret; | 404 int result = 0; |
405 error = handle->node_->GetStat(buf); | |
406 if (error) { | |
407 errno = error; | |
408 result = -1; | |
409 } | |
410 | |
411 ReleaseHandle(handle); | |
412 return result; | |
347 } | 413 } |
348 | 414 |
349 int KernelProxy::getdents(int fd, void* buf, unsigned int count) { | 415 int KernelProxy::getdents(int fd, void* buf, unsigned int count) { |
350 KernelHandle* handle = AcquireHandle(fd); | 416 KernelHandle* handle; |
351 | 417 Error error = AcquireHandle(fd, &handle); |
352 // check if fd is valid and handle exists | 418 if (error) { |
353 if (NULL == handle) return -1; | 419 errno = error; |
354 | 420 return -1; |
355 AutoLock lock(&handle->lock_); | 421 } |
356 int cnt = handle->node_->GetDents(handle->offs_, | 422 |
357 static_cast<dirent *>(buf), count); | 423 AutoLock lock(&handle->lock_); |
358 | 424 int cnt = 0; |
359 if (cnt > 0) handle->offs_ += cnt; | 425 error = handle->node_ |
426 ->GetDents(handle->offs_, static_cast<dirent*>(buf), count, &cnt); | |
427 if (error) | |
428 errno = error; | |
429 | |
430 if (cnt > 0) | |
431 handle->offs_ += cnt; | |
360 | 432 |
361 ReleaseHandle(handle); | 433 ReleaseHandle(handle); |
362 return cnt; | 434 return cnt; |
363 } | 435 } |
364 | 436 |
365 int KernelProxy::ftruncate(int fd, off_t length) { | 437 int KernelProxy::ftruncate(int fd, off_t length) { |
366 KernelHandle* handle = AcquireHandle(fd); | 438 KernelHandle* handle; |
367 | 439 Error error = AcquireHandle(fd, &handle); |
368 // check if fd is valid and handle exists | 440 if (error) { |
369 if (NULL == handle) return -1; | 441 errno = error; |
370 int ret = handle->node_->FTruncate(length); | 442 return -1; |
371 | 443 } |
372 ReleaseHandle(handle); | 444 |
373 return ret; | 445 int result = 0; |
446 error = handle->node_->FTruncate(length); | |
noelallen1
2013/06/07 21:48:43
Should fill with 0 happen here? Is there a way to
binji
2013/06/07 23:23:11
Done.
| |
447 if (error) { | |
448 errno = error; | |
449 result = -1; | |
450 } | |
451 | |
452 ReleaseHandle(handle); | |
453 return result; | |
374 } | 454 } |
375 | 455 |
376 int KernelProxy::fsync(int fd) { | 456 int KernelProxy::fsync(int fd) { |
377 KernelHandle* handle = AcquireHandle(fd); | 457 KernelHandle* handle; |
378 | 458 Error error = AcquireHandle(fd, &handle); |
379 // check if fd is valid and handle exists | 459 if (error) { |
380 if (NULL == handle) return -1; | 460 errno = error; |
381 int ret = handle->node_->FSync(); | 461 return -1; |
382 | 462 } |
383 ReleaseHandle(handle); | 463 |
384 return ret; | 464 int result = 0; |
465 error = handle->node_->FSync(); | |
466 if (error) { | |
467 errno = error; | |
468 result = -1; | |
469 } | |
470 | |
471 ReleaseHandle(handle); | |
472 return result; | |
385 } | 473 } |
386 | 474 |
387 int KernelProxy::isatty(int fd) { | 475 int KernelProxy::isatty(int fd) { |
388 KernelHandle* handle = AcquireHandle(fd); | 476 KernelHandle* handle; |
389 | 477 Error error = AcquireHandle(fd, &handle); |
390 // check if fd is valid and handle exists | 478 if (error) { |
391 if (NULL == handle) return -1; | 479 errno = error; |
392 int ret = handle->node_->IsaTTY(); | 480 return -1; |
393 | 481 } |
394 ReleaseHandle(handle); | 482 |
395 return ret; | 483 int result = 0; |
484 error = handle->node_->IsaTTY(); | |
485 if (error) { | |
486 errno = error; | |
487 result = -1; | |
488 } | |
489 | |
490 ReleaseHandle(handle); | |
491 return result; | |
396 } | 492 } |
397 | 493 |
398 off_t KernelProxy::lseek(int fd, off_t offset, int whence) { | 494 off_t KernelProxy::lseek(int fd, off_t offset, int whence) { |
399 KernelHandle* handle = AcquireHandle(fd); | 495 KernelHandle* handle; |
400 | 496 Error error = AcquireHandle(fd, &handle); |
401 // check if fd is valid and handle exists | 497 if (error) { |
402 if (NULL == handle) return -1; | 498 errno = error; |
403 | 499 return -1; |
404 AutoLock lock(&handle->lock_); | 500 } |
405 int ret = handle->Seek(offset, whence); | 501 |
406 | 502 AutoLock lock(&handle->lock_); |
407 ReleaseHandle(handle); | 503 off_t new_offset; |
408 return ret; | 504 error = handle->Seek(offset, whence, &new_offset); |
505 if (error) { | |
506 errno = error; | |
507 new_offset = -1; | |
508 } | |
509 | |
510 ReleaseHandle(handle); | |
511 return new_offset; | |
409 } | 512 } |
410 | 513 |
411 int KernelProxy::unlink(const char* path) { | 514 int KernelProxy::unlink(const char* path) { |
515 Mount* mnt; | |
412 Path rel; | 516 Path rel; |
413 Mount* mnt = AcquireMountAndPath(path, &rel); | 517 Error error = AcquireMountAndPath(path, &mnt, &rel); |
414 if (mnt == NULL) return -1; | 518 if (error) { |
415 | 519 errno = error; |
416 int val = mnt->Unlink(rel); | 520 return -1; |
521 } | |
522 | |
523 int result = 0; | |
524 error = mnt->Unlink(rel); | |
525 if (error) { | |
526 errno = error; | |
527 result = -1; | |
528 } | |
529 | |
417 ReleaseMount(mnt); | 530 ReleaseMount(mnt); |
418 return val; | 531 return result; |
419 } | 532 } |
420 | 533 |
421 int KernelProxy::remove(const char* path) { | 534 int KernelProxy::remove(const char* path) { |
535 Mount* mnt; | |
422 Path rel; | 536 Path rel; |
423 Mount* mnt = AcquireMountAndPath(path, &rel); | 537 Error error = AcquireMountAndPath(path, &mnt, &rel); |
424 if (mnt == NULL) return -1; | 538 if (error) { |
425 | 539 errno = error; |
426 int val = mnt->Remove(rel); | 540 return -1; |
541 } | |
542 | |
543 int result = 0; | |
544 error = mnt->Remove(rel); | |
545 if (error) { | |
546 errno = error; | |
547 result = -1; | |
548 } | |
549 | |
427 ReleaseMount(mnt); | 550 ReleaseMount(mnt); |
428 return val; | 551 return result; |
429 } | 552 } |
430 | 553 |
431 // TODO(noelallen): Needs implementation. | 554 // TODO(noelallen): Needs implementation. |
432 int KernelProxy::fchmod(int fd, int mode) { | 555 int KernelProxy::fchmod(int fd, int mode) { |
433 errno = EINVAL; | 556 errno = EINVAL; |
434 return -1; | 557 return -1; |
435 } | 558 } |
436 | 559 |
437 int KernelProxy::access(const char* path, int amode) { | 560 int KernelProxy::access(const char* path, int amode) { |
438 errno = EINVAL; | 561 errno = EINVAL; |
439 return -1; | 562 return -1; |
440 } | 563 } |
441 | 564 |
442 int KernelProxy::link(const char* oldpath, const char* newpath) { | 565 int KernelProxy::link(const char* oldpath, const char* newpath) { |
443 errno = EINVAL; | 566 errno = EINVAL; |
444 return -1; | 567 return -1; |
445 } | 568 } |
446 | 569 |
447 int KernelProxy::symlink(const char* oldpath, const char* newpath) { | 570 int KernelProxy::symlink(const char* oldpath, const char* newpath) { |
448 errno = EINVAL; | 571 errno = EINVAL; |
449 return -1; | 572 return -1; |
450 } | 573 } |
451 | 574 |
452 void* KernelProxy::mmap(void* addr, size_t length, int prot, int flags, int fd, | 575 void* KernelProxy::mmap(void* addr, |
576 size_t length, | |
577 int prot, | |
578 int flags, | |
579 int fd, | |
453 size_t offset) { | 580 size_t offset) { |
454 // We shouldn't be getting anonymous mmaps here. | 581 // We shouldn't be getting anonymous mmaps here. |
455 assert((flags & MAP_ANONYMOUS) == 0); | 582 assert((flags & MAP_ANONYMOUS) == 0); |
456 assert(fd != -1); | 583 assert(fd != -1); |
457 | 584 |
458 KernelHandle* handle = AcquireHandle(fd); | 585 KernelHandle* handle; |
459 | 586 Error error = AcquireHandle(fd, &handle); |
460 if (NULL == handle) | 587 if (error) { |
588 errno = error; | |
461 return MAP_FAILED; | 589 return MAP_FAILED; |
590 } | |
462 | 591 |
463 void* new_addr; | 592 void* new_addr; |
464 { | 593 { |
465 AutoLock lock(&handle->lock_); | 594 AutoLock lock(&handle->lock_); |
466 new_addr = handle->node_->MMap(addr, length, prot, flags, offset); | 595 error = handle->node_->MMap(addr, length, prot, flags, offset, &new_addr); |
467 if (new_addr == MAP_FAILED) { | 596 if (error) { |
597 errno = error; | |
468 ReleaseHandle(handle); | 598 ReleaseHandle(handle); |
469 return MAP_FAILED; | 599 return MAP_FAILED; |
470 } | 600 } |
471 } | 601 } |
472 | 602 |
473 ReleaseHandle(handle); | 603 ReleaseHandle(handle); |
474 return new_addr; | 604 return new_addr; |
475 } | 605 } |
476 | 606 |
477 int KernelProxy::munmap(void* addr, size_t length) { | 607 int KernelProxy::munmap(void* addr, size_t length) { |
(...skipping 25 matching lines...) Expand all Loading... | |
503 // ReleaseHandle below which takes the process lock. This is safe as long as | 633 // ReleaseHandle below which takes the process lock. This is safe as long as |
504 // this is never executed from free() -- we can be reasonably sure this is | 634 // this is never executed from free() -- we can be reasonably sure this is |
505 // true, because malloc only makes anonymous mmap() requests, and should only | 635 // true, because malloc only makes anonymous mmap() requests, and should only |
506 // be munmapping those allocations. We never add to mmap_info_list_ for | 636 // be munmapping those allocations. We never add to mmap_info_list_ for |
507 // anonymous maps, so the unmap_list should always be empty when called from | 637 // anonymous maps, so the unmap_list should always be empty when called from |
508 // free(). | 638 // free(). |
509 return 0; | 639 return 0; |
510 } | 640 } |
511 | 641 |
512 int KernelProxy::open_resource(const char* path) { | 642 int KernelProxy::open_resource(const char* path) { |
643 Mount* mnt; | |
513 Path rel; | 644 Path rel; |
645 Error error = AcquireMountAndPath(path, &mnt, &rel); | |
646 if (error) { | |
647 errno = error; | |
648 return -1; | |
649 } | |
514 | 650 |
515 Mount* mnt = AcquireMountAndPath(path, &rel); | 651 MountNode* node = NULL; |
516 if (mnt == NULL) return -1; | 652 error = mnt->OpenResource(rel, &node); |
517 | 653 if (error) { |
518 MountNode* node = mnt->OpenResource(rel); | 654 // OpenResource failed, try Open(). |
519 if (node == NULL) { | 655 error = mnt->Open(rel, O_RDONLY, &node); |
520 node = mnt->Open(rel, O_RDONLY); | 656 if (error) { |
521 if (node == NULL) { | 657 errno = error; |
522 ReleaseMount(mnt); | 658 ReleaseMount(mnt); |
523 return -1; | 659 return -1; |
524 } | 660 } |
525 } | 661 } |
526 | 662 |
527 // OpenResource failed, try Open(). | 663 KernelHandle* handle = new KernelHandle(mnt, node); |
664 error = handle->Init(O_RDONLY); | |
665 if (error) { | |
666 errno = error; | |
667 ReleaseMount(mnt); | |
668 return -1; | |
669 } | |
528 | 670 |
529 KernelHandle* handle = new KernelHandle(mnt, node, O_RDONLY); | |
530 int fd = AllocateFD(handle); | 671 int fd = AllocateFD(handle); |
531 mnt->AcquireNode(node); | 672 mnt->AcquireNode(node); |
532 | 673 |
533 ReleaseHandle(handle); | 674 ReleaseHandle(handle); |
534 ReleaseMount(mnt); | 675 ReleaseMount(mnt); |
535 | 676 |
536 return fd; | 677 return fd; |
537 } | 678 } |
OLD | NEW |