kernel_proxy.cc revision 1e9bf3e0803691d0a228da41fc608347b6db4340
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 3// found in the LICENSE file. 4 5#include "nacl_io/kernel_proxy.h" 6 7#include <assert.h> 8#include <errno.h> 9#include <fcntl.h> 10#include <limits.h> 11#include <poll.h> 12#include <pthread.h> 13#include <stdio.h> 14#include <string.h> 15#include <sys/time.h> 16#include <unistd.h> 17 18#include <iterator> 19#include <string> 20 21#include "nacl_io/host_resolver.h" 22#include "nacl_io/kernel_handle.h" 23#include "nacl_io/kernel_wrap_real.h" 24#include "nacl_io/mount.h" 25#include "nacl_io/mount_dev.h" 26#include "nacl_io/mount_html5fs.h" 27#include "nacl_io/mount_http.h" 28#include "nacl_io/mount_mem.h" 29#include "nacl_io/mount_node.h" 30#include "nacl_io/mount_node_pipe.h" 31#include "nacl_io/mount_node_tcp.h" 32#include "nacl_io/mount_node_udp.h" 33#include "nacl_io/mount_passthrough.h" 34#include "nacl_io/mount_stream.h" 35#include "nacl_io/osmman.h" 36#include "nacl_io/ossocket.h" 37#include "nacl_io/osstat.h" 38#include "nacl_io/path.h" 39#include "nacl_io/pepper_interface.h" 40#include "nacl_io/typed_mount_factory.h" 41#include "sdk_util/auto_lock.h" 42#include "sdk_util/ref_object.h" 43#include "sdk_util/string_util.h" 44 45#ifndef MAXPATHLEN 46#define MAXPATHLEN 256 47#endif 48 49namespace nacl_io { 50 51 52KernelProxy::KernelProxy() : dev_(0), ppapi_(NULL), 53 sigwinch_handler_(SIG_IGN), 54 signal_emitter_(new EventEmitter) { 55 56} 57 58KernelProxy::~KernelProxy() { 59 // Clean up the MountFactories. 60 for (MountFactoryMap_t::iterator i = factories_.begin(); 61 i != factories_.end(); 62 ++i) { 63 delete i->second; 64 } 65 66 delete ppapi_; 67} 68 69Error KernelProxy::Init(PepperInterface* ppapi) { 70 Error rtn = 0; 71 ppapi_ = ppapi; 72 dev_ = 1; 73 74 factories_["memfs"] = new TypedMountFactory<MountMem>; 75 factories_["dev"] = new TypedMountFactory<MountDev>; 76 factories_["html5fs"] = new TypedMountFactory<MountHtml5Fs>; 77 factories_["httpfs"] = new TypedMountFactory<MountHttp>; 78 factories_["passthroughfs"] = new TypedMountFactory<MountPassthrough>; 79 80 int result; 81 result = mount("", "/", "passthroughfs", 0, NULL); 82 if (result != 0) { 83 assert(false); 84 rtn = errno; 85 } 86 87 result = mount("", "/dev", "dev", 0, NULL); 88 if (result != 0) { 89 assert(false); 90 rtn = errno; 91 } 92 93 // Open the first three in order to get STDIN, STDOUT, STDERR 94 int fd; 95 fd = open("/dev/stdin", O_RDONLY); 96 assert(fd == 0); 97 if (fd < 0) 98 rtn = errno; 99 100 fd = open("/dev/stdout", O_WRONLY); 101 assert(fd == 1); 102 if (fd < 0) 103 rtn = errno; 104 105 fd = open("/dev/stderr", O_WRONLY); 106 assert(fd == 2); 107 if (fd < 0) 108 rtn = errno; 109 110#ifdef PROVIDES_SOCKET_API 111 host_resolver_.Init(ppapi_); 112#endif 113 114 StringMap_t args; 115 stream_mount_.reset(new MountStream()); 116 result = stream_mount_->Init(0, args, ppapi); 117 if (result != 0) { 118 assert(false); 119 rtn = result; 120 } 121 122 return rtn; 123} 124 125int KernelProxy::open_resource(const char* path) { 126 ScopedMount mnt; 127 Path rel; 128 129 Error error = AcquireMountAndRelPath(path, &mnt, &rel); 130 if (error) { 131 errno = error; 132 return -1; 133 } 134 135 ScopedMountNode node; 136 error = mnt->OpenResource(rel, &node); 137 if (error) { 138 // OpenResource failed, try Open(). 139 error = mnt->Open(rel, O_RDONLY, &node); 140 if (error) { 141 errno = error; 142 return -1; 143 } 144 } 145 146 ScopedKernelHandle handle(new KernelHandle(mnt, node)); 147 error = handle->Init(O_RDONLY); 148 if (error) { 149 errno = error; 150 return -1; 151 } 152 153 return AllocateFD(handle); 154} 155 156int KernelProxy::open(const char* path, int open_flags) { 157 ScopedMount mnt; 158 ScopedMountNode node; 159 160 Error error = AcquireMountAndNode(path, open_flags, &mnt, &node); 161 if (error) { 162 errno = error; 163 return -1; 164 } 165 166 ScopedKernelHandle handle(new KernelHandle(mnt, node)); 167 error = handle->Init(open_flags); 168 if (error) { 169 errno = error; 170 return -1; 171 } 172 173 return AllocateFD(handle); 174} 175 176int KernelProxy::pipe(int pipefds[2]) { 177 MountNodePipe* pipe = new MountNodePipe(stream_mount_.get()); 178 ScopedMountNode node(pipe); 179 180 if (pipe->Init(S_IREAD | S_IWRITE) == 0) { 181 ScopedKernelHandle handle0(new KernelHandle(stream_mount_, node)); 182 ScopedKernelHandle handle1(new KernelHandle(stream_mount_, node)); 183 184 // Should never fail, but... 185 if (handle0->Init(S_IREAD) || handle1->Init(S_IWRITE)) { 186 errno = EACCES; 187 return -1; 188 } 189 190 pipefds[0] = AllocateFD(handle0); 191 pipefds[1] = AllocateFD(handle1); 192 return 0; 193 } 194 195 errno = ENOSYS; 196 return -1; 197} 198 199int KernelProxy::close(int fd) { 200 ScopedKernelHandle handle; 201 Error error = AcquireHandle(fd, &handle); 202 if (error) { 203 errno = error; 204 return -1; 205 } 206 207 // Remove the FD from the process open file descriptor map 208 FreeFD(fd); 209 return 0; 210} 211 212int KernelProxy::dup(int oldfd) { 213 ScopedKernelHandle handle; 214 Error error = AcquireHandle(oldfd, &handle); 215 if (error) { 216 errno = error; 217 return -1; 218 } 219 220 return AllocateFD(handle); 221} 222 223int KernelProxy::dup2(int oldfd, int newfd) { 224 // If it's the same file handle, just return 225 if (oldfd == newfd) 226 return newfd; 227 228 ScopedKernelHandle old_handle; 229 Error error = AcquireHandle(oldfd, &old_handle); 230 if (error) { 231 errno = error; 232 return -1; 233 } 234 235 FreeAndReassignFD(newfd, old_handle); 236 return newfd; 237} 238 239int KernelProxy::chdir(const char* path) { 240 Error error = SetCWD(path); 241 if (error) { 242 errno = error; 243 return -1; 244 } 245 return 0; 246} 247 248char* KernelProxy::getcwd(char* buf, size_t size) { 249 std::string cwd = GetCWD(); 250 251 if (size <= 0) { 252 errno = EINVAL; 253 return NULL; 254 } 255 256 // If size is 0, allocate as much as we need. 257 if (size == 0) { 258 size = cwd.size() + 1; 259 } 260 261 // Verify the buffer is large enough 262 if (size <= cwd.size()) { 263 errno = ERANGE; 264 return NULL; 265 } 266 267 // Allocate the buffer if needed 268 if (buf == NULL) { 269 buf = static_cast<char*>(malloc(size)); 270 } 271 272 strcpy(buf, cwd.c_str()); 273 return buf; 274} 275 276char* KernelProxy::getwd(char* buf) { 277 if (NULL == buf) { 278 errno = EFAULT; 279 return NULL; 280 } 281 return getcwd(buf, MAXPATHLEN); 282} 283 284int KernelProxy::chmod(const char* path, mode_t mode) { 285 int fd = KernelProxy::open(path, O_RDONLY); 286 if (-1 == fd) 287 return -1; 288 289 int result = fchmod(fd, mode); 290 close(fd); 291 return result; 292} 293 294int KernelProxy::chown(const char* path, uid_t owner, gid_t group) { 295 return 0; 296} 297 298int KernelProxy::fchown(int fd, uid_t owner, gid_t group) { 299 return 0; 300} 301 302int KernelProxy::lchown(const char* path, uid_t owner, gid_t group) { 303 return 0; 304} 305 306int KernelProxy::utime(const char* filename, const struct utimbuf* times) { 307 return 0; 308} 309 310int KernelProxy::mkdir(const char* path, mode_t mode) { 311 ScopedMount mnt; 312 Path rel; 313 314 Error error = AcquireMountAndRelPath(path, &mnt, &rel); 315 if (error) { 316 errno = error; 317 return -1; 318 } 319 320 error = mnt->Mkdir(rel, mode); 321 if (error) { 322 errno = error; 323 return -1; 324 } 325 326 return 0; 327} 328 329int KernelProxy::rmdir(const char* path) { 330 ScopedMount mnt; 331 Path rel; 332 333 Error error = AcquireMountAndRelPath(path, &mnt, &rel); 334 if (error) { 335 errno = error; 336 return -1; 337 } 338 339 error = mnt->Rmdir(rel); 340 if (error) { 341 errno = error; 342 return -1; 343 } 344 345 return 0; 346} 347 348int KernelProxy::stat(const char* path, struct stat* buf) { 349 int fd = open(path, O_RDONLY); 350 if (-1 == fd) 351 return -1; 352 353 int result = fstat(fd, buf); 354 close(fd); 355 return result; 356} 357 358 359int KernelProxy::mount(const char* source, 360 const char* target, 361 const char* filesystemtype, 362 unsigned long mountflags, 363 const void* data) { 364 std::string abs_path = GetAbsParts(target).Join(); 365 366 // Find a factory of that type 367 MountFactoryMap_t::iterator factory = factories_.find(filesystemtype); 368 if (factory == factories_.end()) { 369 errno = ENODEV; 370 return -1; 371 } 372 373 // Create a map of settings 374 StringMap_t smap; 375 smap["SOURCE"] = source; 376 smap["TARGET"] = abs_path; 377 378 if (data) { 379 std::vector<std::string> elements; 380 sdk_util::SplitString(static_cast<const char*>(data), ',', &elements); 381 382 for (std::vector<std::string>::const_iterator it = elements.begin(); 383 it != elements.end(); ++it) { 384 size_t location = it->find('='); 385 if (location != std::string::npos) { 386 std::string key = it->substr(0, location); 387 std::string val = it->substr(location + 1); 388 smap[key] = val; 389 } else { 390 smap[*it] = "TRUE"; 391 } 392 } 393 } 394 395 ScopedMount mnt; 396 Error error = factory->second->CreateMount(dev_++, smap, ppapi_, &mnt); 397 if (error) { 398 errno = error; 399 return -1; 400 } 401 402 error = AttachMountAtPath(mnt, abs_path); 403 if (error) { 404 errno = error; 405 return -1; 406 } 407 408 return 0; 409} 410 411int KernelProxy::umount(const char* path) { 412 Error error = DetachMountAtPath(path); 413 if (error) { 414 errno = error; 415 return -1; 416 } 417 return 0; 418} 419 420ssize_t KernelProxy::read(int fd, void* buf, size_t nbytes) { 421 ScopedKernelHandle handle; 422 Error error = AcquireHandle(fd, &handle); 423 if (error) { 424 errno = error; 425 return -1; 426 } 427 428 int cnt = 0; 429 error = handle->Read(buf, nbytes, &cnt); 430 if (error) { 431 errno = error; 432 return -1; 433 } 434 435 return cnt; 436} 437 438ssize_t KernelProxy::write(int fd, const void* buf, size_t nbytes) { 439 ScopedKernelHandle handle; 440 Error error = AcquireHandle(fd, &handle); 441 if (error) { 442 errno = error; 443 return -1; 444 } 445 446 int cnt = 0; 447 error = handle->Write(buf, nbytes, &cnt); 448 if (error) { 449 errno = error; 450 return -1; 451 } 452 453 return cnt; 454} 455 456int KernelProxy::fstat(int fd, struct stat* buf) { 457 ScopedKernelHandle handle; 458 Error error = AcquireHandle(fd, &handle); 459 if (error) { 460 errno = error; 461 return -1; 462 } 463 464 error = handle->node()->GetStat(buf); 465 if (error) { 466 errno = error; 467 return -1; 468 } 469 470 return 0; 471} 472 473int KernelProxy::getdents(int fd, void* buf, unsigned int count) { 474 ScopedKernelHandle handle; 475 Error error = AcquireHandle(fd, &handle); 476 if (error) { 477 errno = error; 478 return -1; 479 } 480 481 int cnt = 0; 482 error = handle->GetDents(static_cast<dirent*>(buf), count, &cnt); 483 if (error) 484 errno = error; 485 486 return cnt; 487} 488 489int KernelProxy::fchdir(int fd) { 490 errno = ENOSYS; 491 return -1; 492} 493 494int KernelProxy::ftruncate(int fd, off_t length) { 495 ScopedKernelHandle handle; 496 Error error = AcquireHandle(fd, &handle); 497 if (error) { 498 errno = error; 499 return -1; 500 } 501 502 error = handle->node()->FTruncate(length); 503 if (error) { 504 errno = error; 505 return -1; 506 } 507 508 return 0; 509} 510 511int KernelProxy::fsync(int fd) { 512 ScopedKernelHandle handle; 513 Error error = AcquireHandle(fd, &handle); 514 if (error) { 515 errno = error; 516 return -1; 517 } 518 519 error = handle->node()->FSync(); 520 if (error) { 521 errno = error; 522 return -1; 523 } 524 525 return 0; 526} 527 528int KernelProxy::fdatasync(int fd) { 529 errno = ENOSYS; 530 return -1; 531} 532 533int KernelProxy::isatty(int fd) { 534 ScopedKernelHandle handle; 535 Error error = AcquireHandle(fd, &handle); 536 if (error) { 537 errno = error; 538 return -1; 539 } 540 541 error = handle->node()->IsaTTY(); 542 if (error) { 543 errno = error; 544 return -1; 545 } 546 547 return 0; 548} 549 550int KernelProxy::ioctl(int fd, int request, va_list args) { 551 ScopedKernelHandle handle; 552 Error error = AcquireHandle(fd, &handle); 553 if (error) { 554 errno = error; 555 return -1; 556 } 557 558 error = handle->node()->VIoctl(request, args); 559 if (error) { 560 errno = error; 561 return -1; 562 } 563 564 return 0; 565} 566 567off_t KernelProxy::lseek(int fd, off_t offset, int whence) { 568 ScopedKernelHandle handle; 569 Error error = AcquireHandle(fd, &handle); 570 if (error) { 571 errno = error; 572 return -1; 573 } 574 575 off_t new_offset; 576 error = handle->Seek(offset, whence, &new_offset); 577 if (error) { 578 errno = error; 579 return -1; 580 } 581 582 return new_offset; 583} 584 585int KernelProxy::unlink(const char* path) { 586 ScopedMount mnt; 587 Path rel; 588 589 Error error = AcquireMountAndRelPath(path, &mnt, &rel); 590 if (error) { 591 errno = error; 592 return -1; 593 } 594 595 error = mnt->Unlink(rel); 596 if (error) { 597 errno = error; 598 return -1; 599 } 600 601 return 0; 602} 603 604int KernelProxy::truncate(const char* path, off_t len) { 605 errno = ENOSYS; 606 return -1; 607} 608 609int KernelProxy::lstat(const char* path, struct stat* buf) { 610 errno = ENOSYS; 611 return -1; 612} 613 614int KernelProxy::rename(const char* path, const char* newpath) { 615 errno = ENOSYS; 616 return -1; 617} 618 619int KernelProxy::remove(const char* path) { 620 ScopedMount mnt; 621 Path rel; 622 623 Error error = AcquireMountAndRelPath(path, &mnt, &rel); 624 if (error) { 625 errno = error; 626 return -1; 627 } 628 629 error = mnt->Remove(rel); 630 if (error) { 631 errno = error; 632 return -1; 633 } 634 635 return 0; 636} 637 638// TODO(noelallen): Needs implementation. 639int KernelProxy::fchmod(int fd, int mode) { 640 ScopedKernelHandle handle; 641 Error error = AcquireHandle(fd, &handle); 642 if (error) { 643 errno = error; 644 return -1; 645 } 646 647 return 0; 648} 649 650int KernelProxy::fcntl(int fd, int request, va_list args) { 651 Error error = 0; 652 653 // F_GETFD and F_SETFD are descirptor specific flags that 654 // are stored in the KernelObject's decriptor map unlink 655 // F_GETFL and F_SETFL which are handle specific. 656 switch (request) { 657 case F_GETFD: { 658 int rtn = -1; 659 error = GetFDFlags(fd, &rtn); 660 if (error) { 661 errno = error; 662 return -1; 663 } 664 return rtn; 665 } 666 case F_SETFD: { 667 int flags = va_arg(args, int); 668 error = SetFDFlags(fd, flags); 669 if (error) { 670 errno = error; 671 return -1; 672 } 673 return 0; 674 } 675 } 676 677 ScopedKernelHandle handle; 678 error = AcquireHandle(fd, &handle); 679 if (error) { 680 errno = error; 681 return -1; 682 } 683 684 int rtn = 0; 685 error = handle->VFcntl(request, &rtn, args); 686 if (error) { 687 errno = error; 688 return -1; 689 } 690 691 return rtn; 692} 693 694int KernelProxy::access(const char* path, int amode) { 695 ScopedMount mnt; 696 Path rel; 697 698 Error error = AcquireMountAndRelPath(path, &mnt, &rel); 699 if (error) { 700 errno = error; 701 return -1; 702 } 703 704 error = mnt->Access(rel, amode); 705 if (error) { 706 errno = error; 707 return -1; 708 } 709 return 0; 710} 711 712int KernelProxy::readlink(const char *path, char *buf, size_t count) { 713 errno = EINVAL; 714 return -1; 715} 716 717int KernelProxy::utimes(const char *filename, const struct timeval times[2]) { 718 errno = EINVAL; 719 return -1; 720} 721 722// TODO(noelallen): Needs implementation. 723int KernelProxy::link(const char* oldpath, const char* newpath) { 724 errno = EINVAL; 725 return -1; 726} 727 728int KernelProxy::symlink(const char* oldpath, const char* newpath) { 729 errno = EINVAL; 730 return -1; 731} 732 733void* KernelProxy::mmap(void* addr, 734 size_t length, 735 int prot, 736 int flags, 737 int fd, 738 size_t offset) { 739 // We shouldn't be getting anonymous mmaps here. 740 assert((flags & MAP_ANONYMOUS) == 0); 741 assert(fd != -1); 742 743 ScopedKernelHandle handle; 744 Error error = AcquireHandle(fd, &handle); 745 if (error) { 746 errno = error; 747 return MAP_FAILED; 748 } 749 750 void* new_addr; 751 error = handle->node()->MMap(addr, length, prot, flags, offset, &new_addr); 752 if (error) { 753 errno = error; 754 return MAP_FAILED; 755 } 756 757 return new_addr; 758} 759 760int KernelProxy::munmap(void* addr, size_t length) { 761 // NOTE: The comment below is from a previous discarded implementation that 762 // tracks mmap'd regions. For simplicity, we no longer do this; because we 763 // "snapshot" the contents of the file in mmap(), and don't support 764 // write-back or updating the mapped region when the file is written, holding 765 // on to the KernelHandle is pointless. 766 // 767 // If we ever do, these threading issues should be considered. 768 769 // 770 // WARNING: this function may be called by free(). 771 // 772 // There is a potential deadlock scenario: 773 // Thread 1: open() -> takes lock1 -> free() -> takes lock2 774 // Thread 2: free() -> takes lock2 -> munmap() -> takes lock1 775 // 776 // Note that open() above could be any function that takes a lock that is 777 // shared with munmap (this includes munmap!) 778 // 779 // To prevent this, we avoid taking locks in munmap() that are used by other 780 // nacl_io functions that may call free. Specifically, we only take the 781 // mmap_lock, which is only shared with mmap() above. There is still a 782 // possibility of deadlock if mmap() or munmap() calls free(), so this is not 783 // allowed. 784 // 785 // Unfortunately, munmap still needs to acquire other locks; see the call to 786 // ReleaseHandle below which takes the process lock. This is safe as long as 787 // this is never executed from free() -- we can be reasonably sure this is 788 // true, because malloc only makes anonymous mmap() requests, and should only 789 // be munmapping those allocations. We never add to mmap_info_list_ for 790 // anonymous maps, so the unmap_list should always be empty when called from 791 // free(). 792 return 0; 793} 794 795int KernelProxy::tcflush(int fd, int queue_selector) { 796 ScopedKernelHandle handle; 797 Error error = AcquireHandle(fd, &handle); 798 if (error) { 799 errno = error; 800 return -1; 801 } 802 803 error = handle->node()->Tcflush(queue_selector); 804 if (error) { 805 errno = error; 806 return -1; 807 } 808 809 return 0; 810} 811 812int KernelProxy::tcgetattr(int fd, struct termios* termios_p) { 813 ScopedKernelHandle handle; 814 Error error = AcquireHandle(fd, &handle); 815 if (error) { 816 errno = error; 817 return -1; 818 } 819 820 error = handle->node()->Tcgetattr(termios_p); 821 if (error) { 822 errno = error; 823 return -1; 824 } 825 826 return 0; 827} 828 829int KernelProxy::tcsetattr(int fd, int optional_actions, 830 const struct termios *termios_p) { 831 ScopedKernelHandle handle; 832 Error error = AcquireHandle(fd, &handle); 833 if (error) { 834 errno = error; 835 return -1; 836 } 837 838 error = handle->node()->Tcsetattr(optional_actions, termios_p); 839 if (error) { 840 errno = error; 841 return -1; 842 } 843 844 return 0; 845} 846 847int KernelProxy::kill(pid_t pid, int sig) { 848 // Currently we don't even pretend that other processes exist 849 // so we can only send a signal to outselves. For kill(2) 850 // pid 0 means the current process group and -1 means all the 851 // processes we have permission to send signals to. 852 if (pid != getpid() && pid != -1 && pid != 0) { 853 errno = ESRCH; 854 return -1; 855 } 856 857 // Raise an event so that select/poll get interrupted. 858 AUTO_LOCK(signal_emitter_->GetLock()) 859 signal_emitter_->RaiseEvents_Locked(POLLERR); 860 switch (sig) { 861 case SIGWINCH: 862 if (sigwinch_handler_ != SIG_IGN) 863 sigwinch_handler_(SIGWINCH); 864 break; 865 866 case SIGUSR1: 867 case SIGUSR2: 868 break; 869 870 default: 871 errno = EINVAL; 872 return -1; 873 } 874 return 0; 875} 876 877sighandler_t KernelProxy::sigset(int signum, sighandler_t handler) { 878 switch (signum) { 879 // Handled signals. 880 case SIGWINCH: { 881 sighandler_t old_value = sigwinch_handler_; 882 if (handler == SIG_DFL) 883 handler = SIG_IGN; 884 sigwinch_handler_ = handler; 885 return old_value; 886 } 887 888 // Known signals 889 case SIGHUP: 890 case SIGINT: 891 case SIGKILL: 892 case SIGPIPE: 893 case SIGPOLL: 894 case SIGPROF: 895 case SIGTERM: 896 case SIGCHLD: 897 case SIGURG: 898 case SIGFPE: 899 case SIGILL: 900 case SIGQUIT: 901 case SIGSEGV: 902 case SIGTRAP: 903 if (handler == SIG_DFL) 904 return SIG_DFL; 905 break; 906 } 907 908 errno = EINVAL; 909 return SIG_ERR; 910} 911 912#ifdef PROVIDES_SOCKET_API 913 914int KernelProxy::select(int nfds, fd_set* readfds, fd_set* writefds, 915 fd_set* exceptfds, struct timeval* timeout) { 916 fd_set ignore; 917 std::vector<pollfd> pollfds; 918 919 // Simplify logic, by using an IGNORE set for any undefined set 920 FD_ZERO(&ignore); 921 if (NULL == readfds) 922 readfds = &ignore; 923 if (NULL == writefds) 924 writefds = &ignore; 925 if (NULL == exceptfds) 926 exceptfds = &ignore; 927 928 for (int fd = 0; fd < nfds; fd++) { 929 int events = 0; 930 if (FD_ISSET(fd, readfds)) 931 events |= POLLIN; 932 933 if (FD_ISSET(fd, writefds)) 934 events |= POLLOUT; 935 936 if (FD_ISSET(fd, exceptfds)) 937 events |= POLLERR | POLLHUP; 938 939 if (events) { 940 pollfd info; 941 info.fd = fd; 942 info.events = events; 943 pollfds.push_back(info); 944 } 945 } 946 947 FD_ZERO(readfds); 948 FD_ZERO(writefds); 949 FD_ZERO(exceptfds); 950 951 // NULL timeout signals wait forever. 952 int ms_timeout = -1; 953 if (timeout != NULL) { 954 int64_t ms = timeout->tv_sec * 1000 + ((timeout->tv_usec + 500) / 1000); 955 956 // If the timeout is invalid or too long (larger than signed 32 bit). 957 if ((timeout->tv_sec < 0) || (timeout->tv_sec >= (INT_MAX / 1000)) || 958 (timeout->tv_usec < 0) || (timeout->tv_usec >= 1000000) || 959 (ms < 0) || (ms >= INT_MAX)) { 960 errno = EINVAL; 961 return -1; 962 } 963 964 ms_timeout = static_cast<int>(ms); 965 } 966 967 int result = poll(&pollfds[0], pollfds.size(), ms_timeout); 968 if (result == -1) 969 return -1; 970 971 int event_cnt = 0; 972 for (size_t index = 0; index < pollfds.size(); index++) { 973 pollfd* info = &pollfds[index]; 974 if (info->revents & POLLIN) { 975 FD_SET(info->fd, readfds); 976 event_cnt++; 977 } 978 if (info->revents & POLLOUT) { 979 FD_SET(info->fd, writefds); 980 event_cnt++; 981 } 982 if (info->revents & (POLLHUP | POLLERR)) { 983 FD_SET(info->fd, exceptfds); 984 event_cnt++; 985 } 986 } 987 988 return event_cnt; 989} 990 991struct PollInfo { 992 PollInfo() : index(-1) {}; 993 994 std::vector<struct pollfd*> fds; 995 int index; 996}; 997 998typedef std::map<EventEmitter*, PollInfo> EventPollMap_t; 999 1000int KernelProxy::poll(struct pollfd *fds, nfds_t nfds, int timeout) { 1001 EventPollMap_t event_map; 1002 1003 std::vector<EventRequest> requests; 1004 size_t event_cnt = 0; 1005 1006 for (int index = 0; static_cast<nfds_t>(index) < nfds; index++) { 1007 ScopedKernelHandle handle; 1008 struct pollfd* fd_info = &fds[index]; 1009 Error err = AcquireHandle(fd_info->fd, &handle); 1010 1011 fd_info->revents = 0; 1012 1013 // If the node isn't open, or somehow invalid, mark it so. 1014 if (err != 0) { 1015 fd_info->revents = POLLNVAL; 1016 event_cnt++; 1017 continue; 1018 } 1019 1020 // If it's already signaled, then just capture the event 1021 ScopedEventEmitter emitter(handle->node()->GetEventEmitter()); 1022 int events = POLLIN | POLLOUT; 1023 if (emitter) 1024 events = emitter->GetEventStatus(); 1025 1026 if (events & fd_info->events) { 1027 fd_info->revents = events & fd_info->events; 1028 event_cnt++; 1029 continue; 1030 } 1031 1032 if (NULL == emitter) { 1033 fd_info->revents = POLLNVAL; 1034 event_cnt++; 1035 continue; 1036 } 1037 1038 // Otherwise try to track it. 1039 PollInfo* info = &event_map[emitter.get()]; 1040 if (info->index == -1) { 1041 EventRequest request; 1042 request.emitter = emitter; 1043 request.filter = fd_info->events; 1044 request.events = 0; 1045 1046 info->index = requests.size(); 1047 requests.push_back(request); 1048 } 1049 info->fds.push_back(fd_info); 1050 requests[info->index].filter |= fd_info->events; 1051 } 1052 1053 // If nothing is signaled, then we must wait on the event map 1054 if (0 == event_cnt) { 1055 EventListenerPoll wait; 1056 Error err = wait.WaitOnAny(&requests[0], requests.size(), timeout); 1057 if ((err != 0) && (err != ETIMEDOUT)) { 1058 errno = err; 1059 return -1; 1060 } 1061 1062 for (size_t rindex = 0; rindex < requests.size(); rindex++) { 1063 EventRequest* request = &requests[rindex]; 1064 if (request->events) { 1065 PollInfo* poll_info = &event_map[request->emitter.get()]; 1066 for (size_t findex = 0; findex < poll_info->fds.size(); findex++) { 1067 struct pollfd* fd_info = poll_info->fds[findex]; 1068 uint32_t events = fd_info->events & request->events; 1069 if (events) { 1070 fd_info->revents = events; 1071 event_cnt++; 1072 } 1073 } 1074 } 1075 } 1076 } 1077 1078 return event_cnt; 1079} 1080 1081 1082// Socket Functions 1083int KernelProxy::accept(int fd, struct sockaddr* addr, socklen_t* len) { 1084 if (NULL == addr || NULL == len) { 1085 errno = EFAULT; 1086 return -1; 1087 } 1088 1089 ScopedKernelHandle handle; 1090 Error error = AcquireHandle(fd, &handle); 1091 if (error) { 1092 errno = error; 1093 return -1; 1094 } 1095 1096 PP_Resource new_sock = 0; 1097 error = handle->Accept(&new_sock, addr, len); 1098 if (error != 0) { 1099 errno = error; 1100 return -1; 1101 } 1102 1103 MountNodeSocket* sock = new MountNodeTCP(stream_mount_.get(), new_sock); 1104 1105 // The MountNodeSocket now holds a reference to the new socket 1106 // so we release ours. 1107 ppapi_->ReleaseResource(new_sock); 1108 error = sock->Init(S_IREAD | S_IWRITE); 1109 if (error != 0) { 1110 errno = error; 1111 return -1; 1112 } 1113 1114 ScopedMountNode node(sock); 1115 ScopedKernelHandle new_handle(new KernelHandle(stream_mount_, node)); 1116 error = sock->Init(O_RDWR); 1117 if (error != 0) { 1118 errno = error; 1119 return -1; 1120 } 1121 1122 return AllocateFD(new_handle); 1123} 1124 1125int KernelProxy::bind(int fd, const struct sockaddr* addr, socklen_t len) { 1126 if (NULL == addr) { 1127 errno = EFAULT; 1128 return -1; 1129 } 1130 1131 ScopedKernelHandle handle; 1132 if (AcquireSocketHandle(fd, &handle) == -1) 1133 return -1; 1134 1135 Error err = handle->socket_node()->Bind(addr, len); 1136 if (err != 0) { 1137 errno = err; 1138 return -1; 1139 } 1140 1141 return 0; 1142} 1143 1144int KernelProxy::connect(int fd, const struct sockaddr* addr, socklen_t len) { 1145 if (NULL == addr) { 1146 errno = EFAULT; 1147 return -1; 1148 } 1149 1150 ScopedKernelHandle handle; 1151 Error error = AcquireHandle(fd, &handle); 1152 if (error) { 1153 errno = error; 1154 return -1; 1155 } 1156 1157 error = handle->Connect(addr, len); 1158 if (error != 0) { 1159 errno = error; 1160 return -1; 1161 } 1162 1163 return 0; 1164} 1165 1166struct hostent* KernelProxy::gethostbyname(const char* name) { 1167 return host_resolver_.gethostbyname(name); 1168} 1169 1170int KernelProxy::getpeername(int fd, struct sockaddr* addr, socklen_t* len) { 1171 if (NULL == addr || NULL == len) { 1172 errno = EFAULT; 1173 return -1; 1174 } 1175 1176 ScopedKernelHandle handle; 1177 if (AcquireSocketHandle(fd, &handle) == -1) 1178 return -1; 1179 1180 Error err = handle->socket_node()->GetPeerName(addr, len); 1181 if (err != 0) { 1182 errno = err; 1183 return -1; 1184 } 1185 1186 return 0; 1187} 1188 1189int KernelProxy::getsockname(int fd, struct sockaddr* addr, socklen_t* len) { 1190 if (NULL == addr || NULL == len) { 1191 errno = EFAULT; 1192 return -1; 1193 } 1194 1195 ScopedKernelHandle handle; 1196 if (AcquireSocketHandle(fd, &handle) == -1) 1197 return -1; 1198 1199 Error err = handle->socket_node()->GetSockName(addr, len); 1200 if (err != 0) { 1201 errno = err; 1202 return -1; 1203 } 1204 1205 return 0; 1206} 1207 1208int KernelProxy::getsockopt(int fd, 1209 int lvl, 1210 int optname, 1211 void* optval, 1212 socklen_t* len) { 1213 if (NULL == optval || NULL == len) { 1214 errno = EFAULT; 1215 return -1; 1216 } 1217 1218 ScopedKernelHandle handle; 1219 if (AcquireSocketHandle(fd, &handle) == -1) 1220 return -1; 1221 1222 Error err = handle->socket_node()->GetSockOpt(lvl, optname, optval, len); 1223 if (err != 0) { 1224 errno = err; 1225 return -1; 1226 } 1227 1228 return 0; 1229} 1230 1231int KernelProxy::listen(int fd, int backlog) { 1232 ScopedKernelHandle handle; 1233 if (AcquireSocketHandle(fd, &handle) == -1) 1234 return -1; 1235 1236 Error err = handle->socket_node()->Listen(backlog); 1237 if (err != 0) { 1238 errno = err; 1239 return -1; 1240 } 1241 1242 return 0; 1243} 1244 1245ssize_t KernelProxy::recv(int fd, 1246 void* buf, 1247 size_t len, 1248 int flags) { 1249 if (NULL == buf) { 1250 errno = EFAULT; 1251 return -1; 1252 } 1253 1254 ScopedKernelHandle handle; 1255 Error error = AcquireHandle(fd, &handle); 1256 if (error) { 1257 errno = error; 1258 return -1; 1259 } 1260 1261 int out_len = 0; 1262 error = handle->Recv(buf, len, flags, &out_len); 1263 if (error != 0) { 1264 errno = error; 1265 return -1; 1266 } 1267 1268 return static_cast<ssize_t>(out_len); 1269} 1270 1271ssize_t KernelProxy::recvfrom(int fd, 1272 void* buf, 1273 size_t len, 1274 int flags, 1275 struct sockaddr* addr, 1276 socklen_t* addrlen) { 1277 // According to the manpage, recvfrom with a null addr is identical to recv. 1278 if (NULL == addr) { 1279 return recv(fd, buf, len, flags); 1280 } 1281 1282 if (NULL == buf || NULL == addrlen) { 1283 errno = EFAULT; 1284 return -1; 1285 } 1286 1287 ScopedKernelHandle handle; 1288 Error error = AcquireHandle(fd, &handle); 1289 if (error) { 1290 errno = error; 1291 return -1; 1292 } 1293 1294 int out_len = 0; 1295 error = handle->RecvFrom(buf, len, flags, addr, addrlen, &out_len); 1296 if (error != 0) { 1297 errno = error; 1298 return -1; 1299 } 1300 1301 return static_cast<ssize_t>(out_len); 1302} 1303 1304ssize_t KernelProxy::recvmsg(int fd, struct msghdr* msg, int flags) { 1305 if (NULL == msg ) { 1306 errno = EFAULT; 1307 return -1; 1308 } 1309 1310 ScopedKernelHandle handle; 1311 if (AcquireSocketHandle(fd, &handle) == -1) 1312 return -1; 1313 1314 errno = EOPNOTSUPP; 1315 return -1; 1316} 1317 1318ssize_t KernelProxy::send(int fd, const void* buf, size_t len, int flags) { 1319 if (NULL == buf) { 1320 errno = EFAULT; 1321 return -1; 1322 } 1323 1324 ScopedKernelHandle handle; 1325 Error error = AcquireHandle(fd, &handle); 1326 if (error) { 1327 errno = error; 1328 return -1; 1329 } 1330 1331 int out_len = 0; 1332 error = handle->Send(buf, len, flags, &out_len); 1333 if (error != 0) { 1334 errno = error; 1335 return -1; 1336 } 1337 1338 return static_cast<ssize_t>(out_len); 1339} 1340 1341ssize_t KernelProxy::sendto(int fd, 1342 const void* buf, 1343 size_t len, 1344 int flags, 1345 const struct sockaddr* addr, 1346 socklen_t addrlen) { 1347 // According to the manpage, sendto with a null addr is identical to send. 1348 if (NULL == addr) { 1349 return send(fd, buf, len, flags); 1350 } 1351 1352 if (NULL == buf) { 1353 errno = EFAULT; 1354 return -1; 1355 } 1356 1357 ScopedKernelHandle handle; 1358 Error error = AcquireHandle(fd, &handle); 1359 if (error) { 1360 errno = error; 1361 return -1; 1362 } 1363 1364 int out_len = 0; 1365 error = handle->SendTo(buf, len, flags, addr, addrlen, &out_len); 1366 if (error != 0) { 1367 errno = error; 1368 return -1; 1369 } 1370 1371 return static_cast<ssize_t>(out_len); 1372} 1373 1374ssize_t KernelProxy::sendmsg(int fd, const struct msghdr* msg, int flags) { 1375 if (NULL == msg) { 1376 errno = EFAULT; 1377 return -1; 1378 } 1379 1380 ScopedKernelHandle handle; 1381 if (AcquireSocketHandle(fd, &handle) == -1) 1382 return -1; 1383 1384 errno = EOPNOTSUPP; 1385 return -1; 1386} 1387 1388int KernelProxy::setsockopt(int fd, 1389 int lvl, 1390 int optname, 1391 const void* optval, 1392 socklen_t len) { 1393 if (NULL == optval) { 1394 errno = EFAULT; 1395 return -1; 1396 } 1397 1398 ScopedKernelHandle handle; 1399 if (AcquireSocketHandle(fd, &handle) == -1) 1400 return -1; 1401 1402 Error err = handle->socket_node()->SetSockOpt(lvl, optname, optval, len); 1403 if (err != 0) { 1404 errno = err; 1405 return -1; 1406 } 1407 1408 return 0; 1409} 1410 1411int KernelProxy::shutdown(int fd, int how) { 1412 ScopedKernelHandle handle; 1413 if (AcquireSocketHandle(fd, &handle) == -1) 1414 return -1; 1415 1416 Error err = handle->socket_node()->Shutdown(how); 1417 if (err != 0) { 1418 errno = err; 1419 return -1; 1420 } 1421 1422 return 0; 1423} 1424 1425int KernelProxy::socket(int domain, int type, int protocol) { 1426 if (AF_INET != domain && AF_INET6 != domain) { 1427 errno = EAFNOSUPPORT; 1428 return -1; 1429 } 1430 1431 MountNodeSocket* sock = NULL; 1432 switch (type) { 1433 case SOCK_DGRAM: 1434 sock = new MountNodeUDP(stream_mount_.get()); 1435 break; 1436 1437 case SOCK_STREAM: 1438 sock = new MountNodeTCP(stream_mount_.get()); 1439 break; 1440 1441 default: 1442 errno = EPROTONOSUPPORT; 1443 return -1; 1444 } 1445 1446 ScopedMountNode node(sock); 1447 Error rtn = sock->Init(S_IREAD | S_IWRITE); 1448 if (rtn != 0) { 1449 errno = rtn; 1450 return -1; 1451 } 1452 1453 ScopedKernelHandle handle(new KernelHandle(stream_mount_, node)); 1454 rtn = handle->Init(O_RDWR); 1455 if (rtn != 0) { 1456 errno = rtn; 1457 return -1; 1458 } 1459 1460 return AllocateFD(handle); 1461} 1462 1463int KernelProxy::socketpair(int domain, int type, int protocol, int* sv) { 1464 if (NULL == sv) { 1465 errno = EFAULT; 1466 return -1; 1467 } 1468 1469 // Catch-22: We don't support AF_UNIX, but any other AF doesn't support 1470 // socket pairs. Thus, this function always fails. 1471 if (AF_UNIX != domain) { 1472 errno = EPROTONOSUPPORT; 1473 return -1; 1474 } 1475 1476 if (AF_INET != domain && AF_INET6 != domain) { 1477 errno = EAFNOSUPPORT; 1478 return -1; 1479 } 1480 1481 // We cannot reach this point. 1482 errno = ENOSYS; 1483 return -1; 1484} 1485 1486int KernelProxy::AcquireSocketHandle(int fd, ScopedKernelHandle* handle) { 1487 Error error = AcquireHandle(fd, handle); 1488 1489 if (error) { 1490 errno = error; 1491 return -1; 1492 } 1493 1494 if ((handle->get()->node_->GetType() & S_IFSOCK) == 0) { 1495 errno = ENOTSOCK; 1496 return -1; 1497 } 1498 1499 return 0; 1500} 1501 1502#endif // PROVIDES_SOCKET_API 1503 1504} // namespace_nacl_io 1505