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