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