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