Chromium Code Reviews| 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 |