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