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