| 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 <limits.h> | 10 #include <limits.h> |
| 11 #include <poll.h> | 11 #include <poll.h> |
| 12 #include <pthread.h> | 12 #include <pthread.h> |
| 13 #include <stdio.h> | 13 #include <stdio.h> |
| 14 #include <string.h> | 14 #include <string.h> |
| 15 #include <sys/time.h> | 15 #include <sys/time.h> |
| 16 #include <unistd.h> | 16 #include <unistd.h> |
| 17 | 17 |
| 18 #include <iterator> | 18 #include <iterator> |
| 19 #include <string> | 19 #include <string> |
| 20 | 20 |
| 21 #include "nacl_io/devfs/dev_fs.h" | 21 #include "nacl_io/devfs/dev_fs.h" |
| 22 #include "nacl_io/filesystem.h" | 22 #include "nacl_io/filesystem.h" |
| 23 #include "nacl_io/fusefs/fuse_fs_factory.h" | 23 #include "nacl_io/fusefs/fuse_fs_factory.h" |
| 24 #include "nacl_io/host_resolver.h" | 24 #include "nacl_io/host_resolver.h" |
| 25 #include "nacl_io/html5fs/html5_fs.h" | 25 #include "nacl_io/html5fs/html5_fs.h" |
| 26 #include "nacl_io/httpfs/http_fs.h" | 26 #include "nacl_io/httpfs/http_fs.h" |
| 27 #include "nacl_io/kernel_handle.h" | 27 #include "nacl_io/kernel_handle.h" |
| 28 #include "nacl_io/kernel_wrap_real.h" | 28 #include "nacl_io/kernel_wrap_real.h" |
| 29 #include "nacl_io/log.h" |
| 29 #include "nacl_io/memfs/mem_fs.h" | 30 #include "nacl_io/memfs/mem_fs.h" |
| 30 #include "nacl_io/node.h" | 31 #include "nacl_io/node.h" |
| 31 #include "nacl_io/osmman.h" | 32 #include "nacl_io/osmman.h" |
| 32 #include "nacl_io/ossocket.h" | 33 #include "nacl_io/ossocket.h" |
| 33 #include "nacl_io/osstat.h" | 34 #include "nacl_io/osstat.h" |
| 34 #include "nacl_io/passthroughfs/passthrough_fs.h" | 35 #include "nacl_io/passthroughfs/passthrough_fs.h" |
| 35 #include "nacl_io/path.h" | 36 #include "nacl_io/path.h" |
| 36 #include "nacl_io/pepper_interface.h" | 37 #include "nacl_io/pepper_interface.h" |
| 37 #include "nacl_io/pipe/pipe_node.h" | 38 #include "nacl_io/pipe/pipe_node.h" |
| 38 #include "nacl_io/socket/tcp_node.h" | 39 #include "nacl_io/socket/tcp_node.h" |
| 39 #include "nacl_io/socket/udp_node.h" | 40 #include "nacl_io/socket/udp_node.h" |
| 40 #include "nacl_io/stream/stream_fs.h" | 41 #include "nacl_io/stream/stream_fs.h" |
| 41 #include "nacl_io/typed_fs_factory.h" | 42 #include "nacl_io/typed_fs_factory.h" |
| 42 #include "sdk_util/auto_lock.h" | 43 #include "sdk_util/auto_lock.h" |
| 43 #include "sdk_util/ref_object.h" | 44 #include "sdk_util/ref_object.h" |
| 44 #include "sdk_util/string_util.h" | 45 #include "sdk_util/string_util.h" |
| 45 | 46 |
| 46 #ifndef MAXPATHLEN | 47 #ifndef MAXPATHLEN |
| 47 #define MAXPATHLEN 256 | 48 #define MAXPATHLEN 256 |
| 48 #endif | 49 #endif |
| 49 | 50 |
| 50 namespace nacl_io { | 51 namespace nacl_io { |
| 51 | 52 |
| 52 | 53 KernelProxy::KernelProxy() |
| 53 KernelProxy::KernelProxy() : dev_(0), ppapi_(NULL), | 54 : dev_(0), |
| 54 exit_handler_(NULL), | 55 ppapi_(NULL), |
| 55 signal_emitter_(new EventEmitter) { | 56 exit_handler_(NULL), |
| 56 memset(&sigwinch_handler_, 0, sizeof(sigwinch_handler_)); | 57 signal_emitter_(new EventEmitter) { |
| 57 sigwinch_handler_.sa_handler = SIG_DFL; | 58 memset(&sigwinch_handler_, 0, sizeof(sigwinch_handler_)); |
| 59 sigwinch_handler_.sa_handler = SIG_DFL; |
| 58 } | 60 } |
| 59 | 61 |
| 60 KernelProxy::~KernelProxy() { | 62 KernelProxy::~KernelProxy() { |
| 61 // Clean up the MountFactories. | 63 // Clean up the FsFactories. |
| 62 for (FsFactoryMap_t::iterator i = factories_.begin(); i != factories_.end(); | 64 for (FsFactoryMap_t::iterator i = factories_.begin(); i != factories_.end(); |
| 63 ++i) { | 65 ++i) { |
| 64 delete i->second; | 66 delete i->second; |
| 65 } | 67 } |
| 66 } | 68 } |
| 67 | 69 |
| 68 Error KernelProxy::Init(PepperInterface* ppapi) { | 70 Error KernelProxy::Init(PepperInterface* ppapi) { |
| 69 Error rtn = 0; | 71 Error rtn = 0; |
| 70 ppapi_ = ppapi; | 72 ppapi_ = ppapi; |
| 71 dev_ = 1; | 73 dev_ = 1; |
| 72 | 74 |
| 73 factories_["memfs"] = new TypedFsFactory<MemFs>; | 75 factories_["memfs"] = new TypedFsFactory<MemFs>; |
| 74 factories_["dev"] = new TypedFsFactory<DevFs>; | 76 factories_["dev"] = new TypedFsFactory<DevFs>; |
| 75 factories_["html5fs"] = new TypedFsFactory<Html5Fs>; | 77 factories_["html5fs"] = new TypedFsFactory<Html5Fs>; |
| 76 factories_["httpfs"] = new TypedFsFactory<HttpFs>; | 78 factories_["httpfs"] = new TypedFsFactory<HttpFs>; |
| 77 factories_["passthroughfs"] = new TypedFsFactory<PassthroughFs>; | 79 factories_["passthroughfs"] = new TypedFsFactory<PassthroughFs>; |
| 78 | 80 |
| 79 int result; | 81 ScopedFilesystem root_fs; |
| 80 result = mount("", "/", "passthroughfs", 0, NULL); | 82 rtn = MountInternal("", "/", "passthroughfs", 0, NULL, false, &root_fs); |
| 81 if (result != 0) { | 83 if (rtn != 0) |
| 82 assert(false); | 84 assert(false); |
| 83 rtn = errno; | |
| 84 } | |
| 85 | 85 |
| 86 result = mount("", "/dev", "dev", 0, NULL); | 86 ScopedFilesystem fs; |
| 87 if (result != 0) { | 87 rtn = MountInternal("", "/dev", "dev", 0, NULL, false, &fs); |
| 88 if (rtn != 0) |
| 88 assert(false); | 89 assert(false); |
| 89 rtn = errno; | 90 dev_fs_ = sdk_util::static_scoped_ref_cast<DevFs>(fs); |
| 90 } | 91 |
| 92 // Create the filesystem nodes for / and /dev afterward. They can't be |
| 93 // created the normal way because the dev filesystem didn't exist yet. |
| 94 rtn = CreateFsNode(root_fs); |
| 95 if (rtn != 0) |
| 96 assert(false); |
| 97 |
| 98 rtn = CreateFsNode(dev_fs_); |
| 99 if (rtn != 0) |
| 100 assert(false); |
| 91 | 101 |
| 92 // Open the first three in order to get STDIN, STDOUT, STDERR | 102 // Open the first three in order to get STDIN, STDOUT, STDERR |
| 93 int fd; | 103 int fd; |
| 94 fd = open("/dev/stdin", O_RDONLY); | 104 fd = open("/dev/stdin", O_RDONLY); |
| 95 assert(fd == 0); | 105 assert(fd == 0); |
| 96 if (fd < 0) | 106 if (fd < 0) |
| 97 rtn = errno; | 107 rtn = errno; |
| 98 | 108 |
| 99 fd = open("/dev/stdout", O_WRONLY); | 109 fd = open("/dev/stdout", O_WRONLY); |
| 100 assert(fd == 1); | 110 assert(fd == 1); |
| 101 if (fd < 0) | 111 if (fd < 0) |
| 102 rtn = errno; | 112 rtn = errno; |
| 103 | 113 |
| 104 fd = open("/dev/stderr", O_WRONLY); | 114 fd = open("/dev/stderr", O_WRONLY); |
| 105 assert(fd == 2); | 115 assert(fd == 2); |
| 106 if (fd < 0) | 116 if (fd < 0) |
| 107 rtn = errno; | 117 rtn = errno; |
| 108 | 118 |
| 109 #ifdef PROVIDES_SOCKET_API | 119 #ifdef PROVIDES_SOCKET_API |
| 110 host_resolver_.Init(ppapi_); | 120 host_resolver_.Init(ppapi_); |
| 111 #endif | 121 #endif |
| 112 | 122 |
| 113 FsInitArgs args; | 123 FsInitArgs args; |
| 114 args.dev = dev_++; | 124 args.dev = dev_++; |
| 115 args.ppapi = ppapi_; | 125 args.ppapi = ppapi_; |
| 116 stream_mount_.reset(new StreamFs()); | 126 stream_fs_.reset(new StreamFs()); |
| 117 result = stream_mount_->Init(args); | 127 int result = stream_fs_->Init(args); |
| 118 if (result != 0) { | 128 if (result != 0) { |
| 119 assert(false); | 129 assert(false); |
| 120 rtn = result; | 130 rtn = result; |
| 121 } | 131 } |
| 122 | 132 |
| 123 return rtn; | 133 return rtn; |
| 124 } | 134 } |
| 125 | 135 |
| 126 bool KernelProxy::RegisterFsType(const char* fs_type, | 136 bool KernelProxy::RegisterFsType(const char* fs_type, |
| 127 fuse_operations* fuse_ops) { | 137 fuse_operations* fuse_ops) { |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 197 error = handle->Init(open_flags); | 207 error = handle->Init(open_flags); |
| 198 if (error) { | 208 if (error) { |
| 199 errno = error; | 209 errno = error; |
| 200 return -1; | 210 return -1; |
| 201 } | 211 } |
| 202 | 212 |
| 203 return AllocateFD(handle, path); | 213 return AllocateFD(handle, path); |
| 204 } | 214 } |
| 205 | 215 |
| 206 int KernelProxy::pipe(int pipefds[2]) { | 216 int KernelProxy::pipe(int pipefds[2]) { |
| 207 PipeNode* pipe = new PipeNode(stream_mount_.get()); | 217 PipeNode* pipe = new PipeNode(stream_fs_.get()); |
| 208 ScopedNode node(pipe); | 218 ScopedNode node(pipe); |
| 209 | 219 |
| 210 if (pipe->Init(O_RDWR) == 0) { | 220 if (pipe->Init(O_RDWR) == 0) { |
| 211 ScopedKernelHandle handle0(new KernelHandle(stream_mount_, node)); | 221 ScopedKernelHandle handle0(new KernelHandle(stream_fs_, node)); |
| 212 ScopedKernelHandle handle1(new KernelHandle(stream_mount_, node)); | 222 ScopedKernelHandle handle1(new KernelHandle(stream_fs_, node)); |
| 213 | 223 |
| 214 // Should never fail, but... | 224 // Should never fail, but... |
| 215 if (handle0->Init(O_RDONLY) || handle1->Init(O_WRONLY)) { | 225 if (handle0->Init(O_RDONLY) || handle1->Init(O_WRONLY)) { |
| 216 errno = EACCES; | 226 errno = EACCES; |
| 217 return -1; | 227 return -1; |
| 218 } | 228 } |
| 219 | 229 |
| 220 pipefds[0] = AllocateFD(handle0); | 230 pipefds[0] = AllocateFD(handle0); |
| 221 pipefds[1] = AllocateFD(handle1); | 231 pipefds[1] = AllocateFD(handle1); |
| 222 return 0; | 232 return 0; |
| (...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 374 int KernelProxy::stat(const char* path, struct stat* buf) { | 384 int KernelProxy::stat(const char* path, struct stat* buf) { |
| 375 int fd = open(path, O_RDONLY); | 385 int fd = open(path, O_RDONLY); |
| 376 if (-1 == fd) | 386 if (-1 == fd) |
| 377 return -1; | 387 return -1; |
| 378 | 388 |
| 379 int result = fstat(fd, buf); | 389 int result = fstat(fd, buf); |
| 380 close(fd); | 390 close(fd); |
| 381 return result; | 391 return result; |
| 382 } | 392 } |
| 383 | 393 |
| 384 | |
| 385 int KernelProxy::mount(const char* source, | 394 int KernelProxy::mount(const char* source, |
| 386 const char* target, | 395 const char* target, |
| 387 const char* filesystemtype, | 396 const char* filesystemtype, |
| 388 unsigned long mountflags, | 397 unsigned long mountflags, |
| 389 const void* data) { | 398 const void* data) { |
| 399 ScopedFilesystem fs; |
| 400 Error error = MountInternal( |
| 401 source, target, filesystemtype, mountflags, data, true, &fs); |
| 402 if (error) { |
| 403 errno = error; |
| 404 return -1; |
| 405 } |
| 406 |
| 407 return 0; |
| 408 } |
| 409 |
| 410 Error KernelProxy::MountInternal(const char* source, |
| 411 const char* target, |
| 412 const char* filesystemtype, |
| 413 unsigned long mountflags, |
| 414 const void* data, |
| 415 bool create_fs_node, |
| 416 ScopedFilesystem* out_filesystem) { |
| 390 std::string abs_path = GetAbsParts(target).Join(); | 417 std::string abs_path = GetAbsParts(target).Join(); |
| 391 | 418 |
| 392 // Find a factory of that type | 419 // Find a factory of that type |
| 393 FsFactoryMap_t::iterator factory = factories_.find(filesystemtype); | 420 FsFactoryMap_t::iterator factory = factories_.find(filesystemtype); |
| 394 if (factory == factories_.end()) { | 421 if (factory == factories_.end()) |
| 395 errno = ENODEV; | 422 return ENODEV; |
| 396 return -1; | |
| 397 } | |
| 398 | 423 |
| 399 // Create a map of settings | 424 // Create a map of settings |
| 400 StringMap_t smap; | 425 StringMap_t smap; |
| 401 smap["SOURCE"] = source; | 426 smap["SOURCE"] = source; |
| 402 smap["TARGET"] = abs_path; | 427 smap["TARGET"] = abs_path; |
| 403 | 428 |
| 404 if (data) { | 429 if (data) { |
| 405 std::vector<std::string> elements; | 430 std::vector<std::string> elements; |
| 406 sdk_util::SplitString(static_cast<const char*>(data), ',', &elements); | 431 sdk_util::SplitString(static_cast<const char*>(data), ',', &elements); |
| 407 | 432 |
| 408 for (std::vector<std::string>::const_iterator it = elements.begin(); | 433 for (std::vector<std::string>::const_iterator it = elements.begin(); |
| 409 it != elements.end(); ++it) { | 434 it != elements.end(); |
| 435 ++it) { |
| 410 size_t location = it->find('='); | 436 size_t location = it->find('='); |
| 411 if (location != std::string::npos) { | 437 if (location != std::string::npos) { |
| 412 std::string key = it->substr(0, location); | 438 std::string key = it->substr(0, location); |
| 413 std::string val = it->substr(location + 1); | 439 std::string val = it->substr(location + 1); |
| 414 smap[key] = val; | 440 smap[key] = val; |
| 415 } else { | 441 } else { |
| 416 smap[*it] = "TRUE"; | 442 smap[*it] = "TRUE"; |
| 417 } | 443 } |
| 418 } | 444 } |
| 419 } | 445 } |
| 420 | 446 |
| 421 FsInitArgs args; | 447 FsInitArgs args; |
| 422 args.dev = dev_++; | 448 args.dev = dev_++; |
| 423 args.string_map = smap; | 449 args.string_map = smap; |
| 424 args.ppapi = ppapi_; | 450 args.ppapi = ppapi_; |
| 425 | 451 |
| 426 ScopedFilesystem fs; | 452 ScopedFilesystem fs; |
| 427 Error error = factory->second->CreateFilesystem(args, &fs); | 453 Error error = factory->second->CreateFilesystem(args, &fs); |
| 454 if (error) |
| 455 return error; |
| 456 |
| 457 error = AttachFsAtPath(fs, abs_path); |
| 458 if (error) |
| 459 return error; |
| 460 |
| 461 if (create_fs_node) { |
| 462 error = CreateFsNode(fs); |
| 463 if (error) |
| 464 return error; |
| 465 } |
| 466 |
| 467 *out_filesystem = fs; |
| 468 return 0; |
| 469 } |
| 470 |
| 471 Error KernelProxy::CreateFsNode(const ScopedFilesystem& fs) { |
| 472 assert(dev_fs_); |
| 473 |
| 474 return dev_fs_->CreateFsNode(fs.get()); |
| 475 } |
| 476 |
| 477 int KernelProxy::umount(const char* path) { |
| 478 ScopedFilesystem fs; |
| 479 Error error = DetachFsAtPath(path, &fs); |
| 428 if (error) { | 480 if (error) { |
| 429 errno = error; | 481 errno = error; |
| 430 return -1; | 482 return -1; |
| 431 } | 483 } |
| 432 | 484 |
| 433 error = AttachFsAtPath(fs, abs_path); | 485 error = dev_fs_->DestroyFsNode(fs.get()); |
| 434 if (error) { | 486 if (error) { |
| 435 errno = error; | 487 // Ignore any errors here, just log. |
| 436 return -1; | 488 LOG_ERROR("Unable to destroy FsNode: %s", strerror(error)); |
| 437 } | |
| 438 | |
| 439 return 0; | |
| 440 } | |
| 441 | |
| 442 int KernelProxy::umount(const char* path) { | |
| 443 Error error = DetachFsAtPath(path); | |
| 444 if (error) { | |
| 445 errno = error; | |
| 446 return -1; | |
| 447 } | 489 } |
| 448 return 0; | 490 return 0; |
| 449 } | 491 } |
| 450 | 492 |
| 451 ssize_t KernelProxy::read(int fd, void* buf, size_t nbytes) { | 493 ssize_t KernelProxy::read(int fd, void* buf, size_t nbytes) { |
| 452 ScopedKernelHandle handle; | 494 ScopedKernelHandle handle; |
| 453 Error error = AcquireHandle(fd, &handle); | 495 Error error = AcquireHandle(fd, &handle); |
| 454 if (error) { | 496 if (error) { |
| 455 errno = error; | 497 errno = error; |
| 456 return -1; | 498 return -1; |
| (...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 732 errno = error; | 774 errno = error; |
| 733 return -1; | 775 return -1; |
| 734 } | 776 } |
| 735 | 777 |
| 736 return 0; | 778 return 0; |
| 737 } | 779 } |
| 738 | 780 |
| 739 int KernelProxy::fcntl(int fd, int request, va_list args) { | 781 int KernelProxy::fcntl(int fd, int request, va_list args) { |
| 740 Error error = 0; | 782 Error error = 0; |
| 741 | 783 |
| 742 // F_GETFD and F_SETFD are descirptor specific flags that | 784 // F_GETFD and F_SETFD are descriptor specific flags that |
| 743 // are stored in the KernelObject's decriptor map unlink | 785 // are stored in the KernelObject's decriptor map unlike |
| 744 // F_GETFL and F_SETFL which are handle specific. | 786 // F_GETFL and F_SETFL which are handle specific. |
| 745 switch (request) { | 787 switch (request) { |
| 746 case F_GETFD: { | 788 case F_GETFD: { |
| 747 int rtn = -1; | 789 int rtn = -1; |
| 748 error = GetFDFlags(fd, &rtn); | 790 error = GetFDFlags(fd, &rtn); |
| 749 if (error) { | 791 if (error) { |
| 750 errno = error; | 792 errno = error; |
| 751 return -1; | 793 return -1; |
| 752 } | 794 } |
| 753 return rtn; | 795 return rtn; |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 791 } | 833 } |
| 792 | 834 |
| 793 error = fs->Access(rel, amode); | 835 error = fs->Access(rel, amode); |
| 794 if (error) { | 836 if (error) { |
| 795 errno = error; | 837 errno = error; |
| 796 return -1; | 838 return -1; |
| 797 } | 839 } |
| 798 return 0; | 840 return 0; |
| 799 } | 841 } |
| 800 | 842 |
| 801 int KernelProxy::readlink(const char *path, char *buf, size_t count) { | 843 int KernelProxy::readlink(const char* path, char* buf, size_t count) { |
| 802 errno = EINVAL; | 844 errno = EINVAL; |
| 803 return -1; | 845 return -1; |
| 804 } | 846 } |
| 805 | 847 |
| 806 int KernelProxy::utimes(const char *filename, const struct timeval times[2]) { | 848 int KernelProxy::utimes(const char* filename, const struct timeval times[2]) { |
| 807 errno = EINVAL; | 849 errno = EINVAL; |
| 808 return -1; | 850 return -1; |
| 809 } | 851 } |
| 810 | 852 |
| 811 // TODO(noelallen): Needs implementation. | 853 // TODO(noelallen): Needs implementation. |
| 812 int KernelProxy::link(const char* oldpath, const char* newpath) { | 854 int KernelProxy::link(const char* oldpath, const char* newpath) { |
| 813 errno = EINVAL; | 855 errno = EINVAL; |
| 814 return -1; | 856 return -1; |
| 815 } | 857 } |
| 816 | 858 |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 908 | 950 |
| 909 error = handle->node()->Tcgetattr(termios_p); | 951 error = handle->node()->Tcgetattr(termios_p); |
| 910 if (error) { | 952 if (error) { |
| 911 errno = error; | 953 errno = error; |
| 912 return -1; | 954 return -1; |
| 913 } | 955 } |
| 914 | 956 |
| 915 return 0; | 957 return 0; |
| 916 } | 958 } |
| 917 | 959 |
| 918 int KernelProxy::tcsetattr(int fd, int optional_actions, | 960 int KernelProxy::tcsetattr(int fd, |
| 919 const struct termios *termios_p) { | 961 int optional_actions, |
| 962 const struct termios* termios_p) { |
| 920 ScopedKernelHandle handle; | 963 ScopedKernelHandle handle; |
| 921 Error error = AcquireHandle(fd, &handle); | 964 Error error = AcquireHandle(fd, &handle); |
| 922 if (error) { | 965 if (error) { |
| 923 errno = error; | 966 errno = error; |
| 924 return -1; | 967 return -1; |
| 925 } | 968 } |
| 926 | 969 |
| 927 error = handle->node()->Tcsetattr(optional_actions, termios_p); | 970 error = handle->node()->Tcsetattr(optional_actions, termios_p); |
| 928 if (error) { | 971 if (error) { |
| 929 errno = error; | 972 errno = error; |
| (...skipping 28 matching lines...) Expand all Loading... |
| 958 case SIGUSR2: | 1001 case SIGUSR2: |
| 959 break; | 1002 break; |
| 960 | 1003 |
| 961 default: | 1004 default: |
| 962 errno = EINVAL; | 1005 errno = EINVAL; |
| 963 return -1; | 1006 return -1; |
| 964 } | 1007 } |
| 965 return 0; | 1008 return 0; |
| 966 } | 1009 } |
| 967 | 1010 |
| 968 int KernelProxy::sigaction(int signum, const struct sigaction* action, | 1011 int KernelProxy::sigaction(int signum, |
| 1012 const struct sigaction* action, |
| 969 struct sigaction* oaction) { | 1013 struct sigaction* oaction) { |
| 970 if (action && action->sa_flags & SA_SIGINFO) { | 1014 if (action && action->sa_flags & SA_SIGINFO) { |
| 971 // We don't support SA_SIGINFO (sa_sigaction field) yet | 1015 // We don't support SA_SIGINFO (sa_sigaction field) yet |
| 972 errno = EINVAL; | 1016 errno = EINVAL; |
| 973 return -1; | 1017 return -1; |
| 974 } | 1018 } |
| 975 | 1019 |
| 976 switch (signum) { | 1020 switch (signum) { |
| 977 // Handled signals. | 1021 // Handled signals. |
| 978 case SIGWINCH: { | 1022 case SIGWINCH: { |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1018 return -1; | 1062 return -1; |
| 1019 } | 1063 } |
| 1020 | 1064 |
| 1021 // Unknown signum | 1065 // Unknown signum |
| 1022 errno = EINVAL; | 1066 errno = EINVAL; |
| 1023 return -1; | 1067 return -1; |
| 1024 } | 1068 } |
| 1025 | 1069 |
| 1026 #ifdef PROVIDES_SOCKET_API | 1070 #ifdef PROVIDES_SOCKET_API |
| 1027 | 1071 |
| 1028 int KernelProxy::select(int nfds, fd_set* readfds, fd_set* writefds, | 1072 int KernelProxy::select(int nfds, |
| 1029 fd_set* exceptfds, struct timeval* timeout) { | 1073 fd_set* readfds, |
| 1074 fd_set* writefds, |
| 1075 fd_set* exceptfds, |
| 1076 struct timeval* timeout) { |
| 1030 std::vector<pollfd> pollfds; | 1077 std::vector<pollfd> pollfds; |
| 1031 | 1078 |
| 1032 for (int fd = 0; fd < nfds; fd++) { | 1079 for (int fd = 0; fd < nfds; fd++) { |
| 1033 int events = 0; | 1080 int events = 0; |
| 1034 if (readfds && FD_ISSET(fd, readfds)) { | 1081 if (readfds && FD_ISSET(fd, readfds)) { |
| 1035 events |= POLLIN; | 1082 events |= POLLIN; |
| 1036 FD_CLR(fd, readfds); | 1083 FD_CLR(fd, readfds); |
| 1037 } | 1084 } |
| 1038 | 1085 |
| 1039 if (writefds && FD_ISSET(fd, writefds)) { | 1086 if (writefds && FD_ISSET(fd, writefds)) { |
| (...skipping 14 matching lines...) Expand all Loading... |
| 1054 } | 1101 } |
| 1055 } | 1102 } |
| 1056 | 1103 |
| 1057 // NULL timeout signals wait forever. | 1104 // NULL timeout signals wait forever. |
| 1058 int ms_timeout = -1; | 1105 int ms_timeout = -1; |
| 1059 if (timeout != NULL) { | 1106 if (timeout != NULL) { |
| 1060 int64_t ms = timeout->tv_sec * 1000 + ((timeout->tv_usec + 500) / 1000); | 1107 int64_t ms = timeout->tv_sec * 1000 + ((timeout->tv_usec + 500) / 1000); |
| 1061 | 1108 |
| 1062 // If the timeout is invalid or too long (larger than signed 32 bit). | 1109 // If the timeout is invalid or too long (larger than signed 32 bit). |
| 1063 if ((timeout->tv_sec < 0) || (timeout->tv_sec >= (INT_MAX / 1000)) || | 1110 if ((timeout->tv_sec < 0) || (timeout->tv_sec >= (INT_MAX / 1000)) || |
| 1064 (timeout->tv_usec < 0) || (timeout->tv_usec >= 1000000) || | 1111 (timeout->tv_usec < 0) || (timeout->tv_usec >= 1000000) || (ms < 0) || |
| 1065 (ms < 0) || (ms >= INT_MAX)) { | 1112 (ms >= INT_MAX)) { |
| 1066 errno = EINVAL; | 1113 errno = EINVAL; |
| 1067 return -1; | 1114 return -1; |
| 1068 } | 1115 } |
| 1069 | 1116 |
| 1070 ms_timeout = static_cast<int>(ms); | 1117 ms_timeout = static_cast<int>(ms); |
| 1071 } | 1118 } |
| 1072 | 1119 |
| 1073 int result = poll(&pollfds[0], pollfds.size(), ms_timeout); | 1120 int result = poll(&pollfds[0], pollfds.size(), ms_timeout); |
| 1074 if (result == -1) | 1121 if (result == -1) |
| 1075 return -1; | 1122 return -1; |
| (...skipping 20 matching lines...) Expand all Loading... |
| 1096 | 1143 |
| 1097 struct PollInfo { | 1144 struct PollInfo { |
| 1098 PollInfo() : index(-1) {}; | 1145 PollInfo() : index(-1) {}; |
| 1099 | 1146 |
| 1100 std::vector<struct pollfd*> fds; | 1147 std::vector<struct pollfd*> fds; |
| 1101 int index; | 1148 int index; |
| 1102 }; | 1149 }; |
| 1103 | 1150 |
| 1104 typedef std::map<EventEmitter*, PollInfo> EventPollMap_t; | 1151 typedef std::map<EventEmitter*, PollInfo> EventPollMap_t; |
| 1105 | 1152 |
| 1106 int KernelProxy::poll(struct pollfd *fds, nfds_t nfds, int timeout) { | 1153 int KernelProxy::poll(struct pollfd* fds, nfds_t nfds, int timeout) { |
| 1107 EventPollMap_t event_map; | 1154 EventPollMap_t event_map; |
| 1108 | 1155 |
| 1109 std::vector<EventRequest> requests; | 1156 std::vector<EventRequest> requests; |
| 1110 size_t event_cnt = 0; | 1157 size_t event_cnt = 0; |
| 1111 | 1158 |
| 1112 for (int index = 0; static_cast<nfds_t>(index) < nfds; index++) { | 1159 for (int index = 0; static_cast<nfds_t>(index) < nfds; index++) { |
| 1113 ScopedKernelHandle handle; | 1160 ScopedKernelHandle handle; |
| 1114 struct pollfd* fd_info = &fds[index]; | 1161 struct pollfd* fd_info = &fds[index]; |
| 1115 Error err = AcquireHandle(fd_info->fd, &handle); | 1162 Error err = AcquireHandle(fd_info->fd, &handle); |
| 1116 | 1163 |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1177 event_cnt++; | 1224 event_cnt++; |
| 1178 } | 1225 } |
| 1179 } | 1226 } |
| 1180 } | 1227 } |
| 1181 } | 1228 } |
| 1182 } | 1229 } |
| 1183 | 1230 |
| 1184 return event_cnt; | 1231 return event_cnt; |
| 1185 } | 1232 } |
| 1186 | 1233 |
| 1187 | |
| 1188 // Socket Functions | 1234 // Socket Functions |
| 1189 int KernelProxy::accept(int fd, struct sockaddr* addr, socklen_t* len) { | 1235 int KernelProxy::accept(int fd, struct sockaddr* addr, socklen_t* len) { |
| 1190 if (NULL == addr || NULL == len) { | 1236 if (NULL == addr || NULL == len) { |
| 1191 errno = EFAULT; | 1237 errno = EFAULT; |
| 1192 return -1; | 1238 return -1; |
| 1193 } | 1239 } |
| 1194 | 1240 |
| 1195 ScopedKernelHandle handle; | 1241 ScopedKernelHandle handle; |
| 1196 Error error = AcquireHandle(fd, &handle); | 1242 Error error = AcquireHandle(fd, &handle); |
| 1197 if (error) { | 1243 if (error) { |
| 1198 errno = error; | 1244 errno = error; |
| 1199 return -1; | 1245 return -1; |
| 1200 } | 1246 } |
| 1201 | 1247 |
| 1202 PP_Resource new_sock = 0; | 1248 PP_Resource new_sock = 0; |
| 1203 error = handle->Accept(&new_sock, addr, len); | 1249 error = handle->Accept(&new_sock, addr, len); |
| 1204 if (error != 0) { | 1250 if (error != 0) { |
| 1205 errno = error; | 1251 errno = error; |
| 1206 return -1; | 1252 return -1; |
| 1207 } | 1253 } |
| 1208 | 1254 |
| 1209 SocketNode* sock = new TcpNode(stream_mount_.get(), new_sock); | 1255 SocketNode* sock = new TcpNode(stream_fs_.get(), new_sock); |
| 1210 | 1256 |
| 1211 // The SocketNode now holds a reference to the new socket | 1257 // The SocketNode now holds a reference to the new socket |
| 1212 // so we release ours. | 1258 // so we release ours. |
| 1213 ppapi_->ReleaseResource(new_sock); | 1259 ppapi_->ReleaseResource(new_sock); |
| 1214 error = sock->Init(O_RDWR); | 1260 error = sock->Init(O_RDWR); |
| 1215 if (error != 0) { | 1261 if (error != 0) { |
| 1216 errno = error; | 1262 errno = error; |
| 1217 return -1; | 1263 return -1; |
| 1218 } | 1264 } |
| 1219 | 1265 |
| 1220 ScopedNode node(sock); | 1266 ScopedNode node(sock); |
| 1221 ScopedKernelHandle new_handle(new KernelHandle(stream_mount_, node)); | 1267 ScopedKernelHandle new_handle(new KernelHandle(stream_fs_, node)); |
| 1222 error = new_handle->Init(O_RDWR); | 1268 error = new_handle->Init(O_RDWR); |
| 1223 if (error != 0) { | 1269 if (error != 0) { |
| 1224 errno = error; | 1270 errno = error; |
| 1225 return -1; | 1271 return -1; |
| 1226 } | 1272 } |
| 1227 | 1273 |
| 1228 return AllocateFD(new_handle); | 1274 return AllocateFD(new_handle); |
| 1229 } | 1275 } |
| 1230 | 1276 |
| 1231 int KernelProxy::bind(int fd, const struct sockaddr* addr, socklen_t len) { | 1277 int KernelProxy::bind(int fd, const struct sockaddr* addr, socklen_t len) { |
| (...skipping 30 matching lines...) Expand all Loading... |
| 1262 | 1308 |
| 1263 error = handle->Connect(addr, len); | 1309 error = handle->Connect(addr, len); |
| 1264 if (error != 0) { | 1310 if (error != 0) { |
| 1265 errno = error; | 1311 errno = error; |
| 1266 return -1; | 1312 return -1; |
| 1267 } | 1313 } |
| 1268 | 1314 |
| 1269 return 0; | 1315 return 0; |
| 1270 } | 1316 } |
| 1271 | 1317 |
| 1272 void KernelProxy::freeaddrinfo(struct addrinfo *res) { | 1318 void KernelProxy::freeaddrinfo(struct addrinfo* res) { |
| 1273 return host_resolver_.freeaddrinfo(res); | 1319 return host_resolver_.freeaddrinfo(res); |
| 1274 } | 1320 } |
| 1275 | 1321 |
| 1276 int KernelProxy::getaddrinfo(const char* node, const char* service, | 1322 int KernelProxy::getaddrinfo(const char* node, |
| 1323 const char* service, |
| 1277 const struct addrinfo* hints, | 1324 const struct addrinfo* hints, |
| 1278 struct addrinfo** res) { | 1325 struct addrinfo** res) { |
| 1279 return host_resolver_.getaddrinfo(node, service, hints, res); | 1326 return host_resolver_.getaddrinfo(node, service, hints, res); |
| 1280 } | 1327 } |
| 1281 | 1328 |
| 1282 struct hostent* KernelProxy::gethostbyname(const char* name) { | 1329 struct hostent* KernelProxy::gethostbyname(const char* name) { |
| 1283 return host_resolver_.gethostbyname(name); | 1330 return host_resolver_.gethostbyname(name); |
| 1284 } | 1331 } |
| 1285 | 1332 |
| 1286 int KernelProxy::getpeername(int fd, struct sockaddr* addr, socklen_t* len) { | 1333 int KernelProxy::getpeername(int fd, struct sockaddr* addr, socklen_t* len) { |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1351 | 1398 |
| 1352 Error err = handle->socket_node()->Listen(backlog); | 1399 Error err = handle->socket_node()->Listen(backlog); |
| 1353 if (err != 0) { | 1400 if (err != 0) { |
| 1354 errno = err; | 1401 errno = err; |
| 1355 return -1; | 1402 return -1; |
| 1356 } | 1403 } |
| 1357 | 1404 |
| 1358 return 0; | 1405 return 0; |
| 1359 } | 1406 } |
| 1360 | 1407 |
| 1361 ssize_t KernelProxy::recv(int fd, | 1408 ssize_t KernelProxy::recv(int fd, void* buf, size_t len, int flags) { |
| 1362 void* buf, | |
| 1363 size_t len, | |
| 1364 int flags) { | |
| 1365 if (NULL == buf) { | 1409 if (NULL == buf) { |
| 1366 errno = EFAULT; | 1410 errno = EFAULT; |
| 1367 return -1; | 1411 return -1; |
| 1368 } | 1412 } |
| 1369 | 1413 |
| 1370 ScopedKernelHandle handle; | 1414 ScopedKernelHandle handle; |
| 1371 Error error = AcquireHandle(fd, &handle); | 1415 Error error = AcquireHandle(fd, &handle); |
| 1372 if (error) { | 1416 if (error) { |
| 1373 errno = error; | 1417 errno = error; |
| 1374 return -1; | 1418 return -1; |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1411 error = handle->RecvFrom(buf, len, flags, addr, addrlen, &out_len); | 1455 error = handle->RecvFrom(buf, len, flags, addr, addrlen, &out_len); |
| 1412 if (error != 0) { | 1456 if (error != 0) { |
| 1413 errno = error; | 1457 errno = error; |
| 1414 return -1; | 1458 return -1; |
| 1415 } | 1459 } |
| 1416 | 1460 |
| 1417 return static_cast<ssize_t>(out_len); | 1461 return static_cast<ssize_t>(out_len); |
| 1418 } | 1462 } |
| 1419 | 1463 |
| 1420 ssize_t KernelProxy::recvmsg(int fd, struct msghdr* msg, int flags) { | 1464 ssize_t KernelProxy::recvmsg(int fd, struct msghdr* msg, int flags) { |
| 1421 if (NULL == msg ) { | 1465 if (NULL == msg) { |
| 1422 errno = EFAULT; | 1466 errno = EFAULT; |
| 1423 return -1; | 1467 return -1; |
| 1424 } | 1468 } |
| 1425 | 1469 |
| 1426 ScopedKernelHandle handle; | 1470 ScopedKernelHandle handle; |
| 1427 if (AcquireSocketHandle(fd, &handle) == -1) | 1471 if (AcquireSocketHandle(fd, &handle) == -1) |
| 1428 return -1; | 1472 return -1; |
| 1429 | 1473 |
| 1430 errno = EOPNOTSUPP; | 1474 errno = EOPNOTSUPP; |
| 1431 return -1; | 1475 return -1; |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1557 } | 1601 } |
| 1558 | 1602 |
| 1559 if (type & SOCK_NONBLOCK) { | 1603 if (type & SOCK_NONBLOCK) { |
| 1560 open_flags |= O_NONBLOCK; | 1604 open_flags |= O_NONBLOCK; |
| 1561 type &= ~SOCK_NONBLOCK; | 1605 type &= ~SOCK_NONBLOCK; |
| 1562 } | 1606 } |
| 1563 | 1607 |
| 1564 SocketNode* sock = NULL; | 1608 SocketNode* sock = NULL; |
| 1565 switch (type) { | 1609 switch (type) { |
| 1566 case SOCK_DGRAM: | 1610 case SOCK_DGRAM: |
| 1567 sock = new UdpNode(stream_mount_.get()); | 1611 sock = new UdpNode(stream_fs_.get()); |
| 1568 break; | 1612 break; |
| 1569 | 1613 |
| 1570 case SOCK_STREAM: | 1614 case SOCK_STREAM: |
| 1571 sock = new TcpNode(stream_mount_.get()); | 1615 sock = new TcpNode(stream_fs_.get()); |
| 1572 break; | 1616 break; |
| 1573 | 1617 |
| 1574 case SOCK_SEQPACKET: | 1618 case SOCK_SEQPACKET: |
| 1575 case SOCK_RDM: | 1619 case SOCK_RDM: |
| 1576 case SOCK_RAW: | 1620 case SOCK_RAW: |
| 1577 errno = EPROTONOSUPPORT; | 1621 errno = EPROTONOSUPPORT; |
| 1578 return -1; | 1622 return -1; |
| 1579 | 1623 |
| 1580 default: | 1624 default: |
| 1581 errno = EINVAL; | 1625 errno = EINVAL; |
| 1582 return -1; | 1626 return -1; |
| 1583 } | 1627 } |
| 1584 | 1628 |
| 1585 ScopedNode node(sock); | 1629 ScopedNode node(sock); |
| 1586 Error rtn = sock->Init(O_RDWR); | 1630 Error rtn = sock->Init(O_RDWR); |
| 1587 if (rtn != 0) { | 1631 if (rtn != 0) { |
| 1588 errno = rtn; | 1632 errno = rtn; |
| 1589 return -1; | 1633 return -1; |
| 1590 } | 1634 } |
| 1591 | 1635 |
| 1592 ScopedKernelHandle handle(new KernelHandle(stream_mount_, node)); | 1636 ScopedKernelHandle handle(new KernelHandle(stream_fs_, node)); |
| 1593 rtn = handle->Init(open_flags); | 1637 rtn = handle->Init(open_flags); |
| 1594 if (rtn != 0) { | 1638 if (rtn != 0) { |
| 1595 errno = rtn; | 1639 errno = rtn; |
| 1596 return -1; | 1640 return -1; |
| 1597 } | 1641 } |
| 1598 | 1642 |
| 1599 return AllocateFD(handle); | 1643 return AllocateFD(handle); |
| 1600 } | 1644 } |
| 1601 | 1645 |
| 1602 int KernelProxy::socketpair(int domain, int type, int protocol, int* sv) { | 1646 int KernelProxy::socketpair(int domain, int type, int protocol, int* sv) { |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1634 errno = ENOTSOCK; | 1678 errno = ENOTSOCK; |
| 1635 return -1; | 1679 return -1; |
| 1636 } | 1680 } |
| 1637 | 1681 |
| 1638 return 0; | 1682 return 0; |
| 1639 } | 1683 } |
| 1640 | 1684 |
| 1641 #endif // PROVIDES_SOCKET_API | 1685 #endif // PROVIDES_SOCKET_API |
| 1642 | 1686 |
| 1643 } // namespace_nacl_io | 1687 } // namespace_nacl_io |
| OLD | NEW |