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