1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "nacl_io/kernel_proxy.h" 6 7 8 #include <assert.h> 9 #include <errno.h> 10 #include <fcntl.h> 11 #include <limits.h> 12 #include <poll.h> 13 #include <pthread.h> 14 #include <stdio.h> 15 #include <string.h> 16 #include <sys/time.h> 17 18 #include <iterator> 19 #include <string> 20 21 #include "nacl_io/host_resolver.h" 22 #include "nacl_io/kernel_handle.h" 23 #include "nacl_io/kernel_wrap_real.h" 24 #include "nacl_io/mount.h" 25 #include "nacl_io/mount_dev.h" 26 #include "nacl_io/mount_html5fs.h" 27 #include "nacl_io/mount_http.h" 28 #include "nacl_io/mount_mem.h" 29 #include "nacl_io/mount_node.h" 30 #include "nacl_io/mount_passthrough.h" 31 #include "nacl_io/osmman.h" 32 #include "nacl_io/ossocket.h" 33 #include "nacl_io/osstat.h" 34 #include "nacl_io/path.h" 35 #include "nacl_io/pepper_interface.h" 36 #include "nacl_io/typed_mount_factory.h" 37 #include "sdk_util/auto_lock.h" 38 #include "sdk_util/ref_object.h" 39 40 #ifndef MAXPATHLEN 41 #define MAXPATHLEN 256 42 #endif 43 44 namespace nacl_io { 45 46 KernelProxy::KernelProxy() : dev_(0), ppapi_(NULL) { 47 } 48 49 KernelProxy::~KernelProxy() { 50 // Clean up the MountFactories. 51 for (MountFactoryMap_t::iterator i = factories_.begin(); 52 i != factories_.end(); 53 ++i) { 54 delete i->second; 55 } 56 57 delete ppapi_; 58 } 59 60 void KernelProxy::Init(PepperInterface* ppapi) { 61 ppapi_ = ppapi; 62 dev_ = 1; 63 64 factories_["memfs"] = new TypedMountFactory<MountMem>; 65 factories_["dev"] = new TypedMountFactory<MountDev>; 66 factories_["html5fs"] = new TypedMountFactory<MountHtml5Fs>; 67 factories_["httpfs"] = new TypedMountFactory<MountHttp>; 68 factories_["passthroughfs"] = new TypedMountFactory<MountPassthrough>; 69 70 int result; 71 result = mount("", "/", "passthroughfs", 0, NULL); 72 assert(result == 0); 73 74 result = mount("", "/dev", "dev", 0, NULL); 75 assert(result == 0); 76 77 // Open the first three in order to get STDIN, STDOUT, STDERR 78 open("/dev/stdin", O_RDONLY); 79 open("/dev/stdout", O_WRONLY); 80 open("/dev/stderr", O_WRONLY); 81 82 #ifdef PROVIDES_SOCKET_API 83 host_resolver_.Init(ppapi_); 84 #endif 85 } 86 87 int KernelProxy::open_resource(const char* path) { 88 ScopedMount mnt; 89 Path rel; 90 91 Error error = AcquireMountAndRelPath(path, &mnt, &rel); 92 if (error) { 93 errno = error; 94 return -1; 95 } 96 97 ScopedMountNode node; 98 error = mnt->OpenResource(rel, &node); 99 if (error) { 100 // OpenResource failed, try Open(). 101 error = mnt->Open(rel, O_RDONLY, &node); 102 if (error) { 103 errno = error; 104 return -1; 105 } 106 } 107 108 ScopedKernelHandle handle(new KernelHandle(mnt, node)); 109 error = handle->Init(O_RDONLY); 110 if (error) { 111 errno = error; 112 return -1; 113 } 114 115 return AllocateFD(handle); 116 } 117 118 int KernelProxy::open(const char* path, int oflags) { 119 ScopedMount mnt; 120 ScopedMountNode node; 121 122 Error error = AcquireMountAndNode(path, oflags, &mnt, &node); 123 if (error) { 124 errno = error; 125 return -1; 126 } 127 128 ScopedKernelHandle handle(new KernelHandle(mnt, node)); 129 error = handle->Init(oflags); 130 if (error) { 131 errno = error; 132 return -1; 133 } 134 135 return AllocateFD(handle); 136 } 137 138 int KernelProxy::close(int fd) { 139 ScopedKernelHandle handle; 140 Error error = AcquireHandle(fd, &handle); 141 if (error) { 142 errno = error; 143 return -1; 144 } 145 146 // Remove the FD from the process open file descriptor map 147 FreeFD(fd); 148 return 0; 149 } 150 151 int KernelProxy::dup(int oldfd) { 152 ScopedKernelHandle handle; 153 Error error = AcquireHandle(oldfd, &handle); 154 if (error) { 155 errno = error; 156 return -1; 157 } 158 159 return AllocateFD(handle); 160 } 161 162 int KernelProxy::dup2(int oldfd, int newfd) { 163 // If it's the same file handle, just return 164 if (oldfd == newfd) 165 return newfd; 166 167 ScopedKernelHandle old_handle; 168 Error error = AcquireHandle(oldfd, &old_handle); 169 if (error) { 170 errno = error; 171 return -1; 172 } 173 174 FreeAndReassignFD(newfd, old_handle); 175 return newfd; 176 } 177 178 int KernelProxy::chdir(const char* path) { 179 Error error = SetCWD(path); 180 if (error) { 181 errno = error; 182 return -1; 183 } 184 return 0; 185 } 186 187 char* KernelProxy::getcwd(char* buf, size_t size) { 188 std::string cwd = GetCWD(); 189 190 if (size <= 0) { 191 errno = EINVAL; 192 return NULL; 193 } 194 195 // If size is 0, allocate as much as we need. 196 if (size == 0) { 197 size = cwd.size() + 1; 198 } 199 200 // Verify the buffer is large enough 201 if (size <= cwd.size()) { 202 errno = ERANGE; 203 return NULL; 204 } 205 206 // Allocate the buffer if needed 207 if (buf == NULL) { 208 buf = static_cast<char*>(malloc(size)); 209 } 210 211 strcpy(buf, cwd.c_str()); 212 return buf; 213 } 214 215 char* KernelProxy::getwd(char* buf) { 216 if (NULL == buf) { 217 errno = EFAULT; 218 return NULL; 219 } 220 return getcwd(buf, MAXPATHLEN); 221 } 222 223 int KernelProxy::chmod(const char* path, mode_t mode) { 224 int fd = KernelProxy::open(path, O_RDONLY); 225 if (-1 == fd) 226 return -1; 227 228 int result = fchmod(fd, mode); 229 close(fd); 230 return result; 231 } 232 233 int KernelProxy::chown(const char* path, uid_t owner, gid_t group) { 234 return 0; 235 } 236 237 int KernelProxy::fchown(int fd, uid_t owner, gid_t group) { 238 return 0; 239 } 240 241 int KernelProxy::lchown(const char* path, uid_t owner, gid_t group) { 242 return 0; 243 } 244 245 int KernelProxy::utime(const char* filename, const struct utimbuf* times) { 246 return 0; 247 } 248 249 int KernelProxy::mkdir(const char* path, mode_t mode) { 250 ScopedMount mnt; 251 Path rel; 252 253 Error error = AcquireMountAndRelPath(path, &mnt, &rel); 254 if (error) { 255 errno = error; 256 return -1; 257 } 258 259 error = mnt->Mkdir(rel, mode); 260 if (error) { 261 errno = error; 262 return -1; 263 } 264 265 return 0; 266 } 267 268 int KernelProxy::rmdir(const char* path) { 269 ScopedMount mnt; 270 Path rel; 271 272 Error error = AcquireMountAndRelPath(path, &mnt, &rel); 273 if (error) { 274 errno = error; 275 return -1; 276 } 277 278 error = mnt->Rmdir(rel); 279 if (error) { 280 errno = error; 281 return -1; 282 } 283 284 return 0; 285 } 286 287 int KernelProxy::stat(const char* path, struct stat* buf) { 288 int fd = open(path, O_RDONLY); 289 if (-1 == fd) 290 return -1; 291 292 int result = fstat(fd, buf); 293 close(fd); 294 return result; 295 } 296 297 298 int KernelProxy::mount(const char* source, 299 const char* target, 300 const char* filesystemtype, 301 unsigned long mountflags, 302 const void* data) { 303 std::string abs_path = GetAbsParts(target).Join(); 304 305 // Find a factory of that type 306 MountFactoryMap_t::iterator factory = factories_.find(filesystemtype); 307 if (factory == factories_.end()) { 308 errno = ENODEV; 309 return -1; 310 } 311 312 // Create a map of settings 313 StringMap_t smap; 314 smap["SOURCE"] = source; 315 smap["TARGET"] = abs_path; 316 317 if (data) { 318 char* str = strdup(static_cast<const char*>(data)); 319 char* ptr = strtok(str, ","); 320 char* val; 321 while (ptr != NULL) { 322 val = strchr(ptr, '='); 323 if (val) { 324 *val = 0; 325 smap[ptr] = val + 1; 326 } else { 327 smap[ptr] = "TRUE"; 328 } 329 ptr = strtok(NULL, ","); 330 } 331 free(str); 332 } 333 334 ScopedMount mnt; 335 Error error = factory->second->CreateMount(dev_++, smap, ppapi_, &mnt); 336 if (error) { 337 errno = error; 338 return -1; 339 } 340 341 error = AttachMountAtPath(mnt, abs_path); 342 if (error) { 343 errno = error; 344 return -1; 345 } 346 347 return 0; 348 } 349 350 int KernelProxy::umount(const char* path) { 351 Error error = DetachMountAtPath(path); 352 if (error) { 353 errno = error; 354 return -1; 355 } 356 return 0; 357 } 358 359 ssize_t KernelProxy::read(int fd, void* buf, size_t nbytes) { 360 ScopedKernelHandle handle; 361 Error error = AcquireHandle(fd, &handle); 362 if (error) { 363 errno = error; 364 return -1; 365 } 366 367 int cnt = 0; 368 error = handle->Read(buf, nbytes, &cnt); 369 if (error) { 370 errno = error; 371 return -1; 372 } 373 374 return cnt; 375 } 376 377 ssize_t KernelProxy::write(int fd, const void* buf, size_t nbytes) { 378 ScopedKernelHandle handle; 379 Error error = AcquireHandle(fd, &handle); 380 if (error) { 381 errno = error; 382 return -1; 383 } 384 385 int cnt = 0; 386 error = handle->Write(buf, nbytes, &cnt); 387 if (error) { 388 errno = error; 389 return -1; 390 } 391 392 return cnt; 393 } 394 395 int KernelProxy::fstat(int fd, struct stat* buf) { 396 ScopedKernelHandle handle; 397 Error error = AcquireHandle(fd, &handle); 398 if (error) { 399 errno = error; 400 return -1; 401 } 402 403 error = handle->node()->GetStat(buf); 404 if (error) { 405 errno = error; 406 return -1; 407 } 408 409 return 0; 410 } 411 412 int KernelProxy::getdents(int fd, void* buf, unsigned int count) { 413 ScopedKernelHandle handle; 414 Error error = AcquireHandle(fd, &handle); 415 if (error) { 416 errno = error; 417 return -1; 418 } 419 420 int cnt = 0; 421 error = handle->GetDents(static_cast<dirent*>(buf), count, &cnt); 422 if (error) 423 errno = error; 424 425 return cnt; 426 } 427 428 int KernelProxy::ftruncate(int fd, off_t length) { 429 ScopedKernelHandle handle; 430 Error error = AcquireHandle(fd, &handle); 431 if (error) { 432 errno = error; 433 return -1; 434 } 435 436 error = handle->node()->FTruncate(length); 437 if (error) { 438 errno = error; 439 return -1; 440 } 441 442 return 0; 443 } 444 445 int KernelProxy::fsync(int fd) { 446 ScopedKernelHandle handle; 447 Error error = AcquireHandle(fd, &handle); 448 if (error) { 449 errno = error; 450 return -1; 451 } 452 453 error = handle->node()->FSync(); 454 if (error) { 455 errno = error; 456 return -1; 457 } 458 459 return 0; 460 } 461 462 int KernelProxy::isatty(int fd) { 463 ScopedKernelHandle handle; 464 Error error = AcquireHandle(fd, &handle); 465 if (error) { 466 errno = error; 467 return -1; 468 } 469 470 error = handle->node()->IsaTTY(); 471 if (error) { 472 errno = error; 473 return -1; 474 } 475 476 return 0; 477 } 478 479 int KernelProxy::ioctl(int fd, int request, char* argp) { 480 ScopedKernelHandle handle; 481 Error error = AcquireHandle(fd, &handle); 482 if (error) { 483 errno = error; 484 return -1; 485 } 486 487 error = handle->node()->Ioctl(request, argp); 488 if (error) { 489 errno = error; 490 return -1; 491 } 492 493 return 0; 494 } 495 496 off_t KernelProxy::lseek(int fd, off_t offset, int whence) { 497 ScopedKernelHandle handle; 498 Error error = AcquireHandle(fd, &handle); 499 if (error) { 500 errno = error; 501 return -1; 502 } 503 504 off_t new_offset; 505 error = handle->Seek(offset, whence, &new_offset); 506 if (error) { 507 errno = error; 508 return -1; 509 } 510 511 return new_offset; 512 } 513 514 int KernelProxy::unlink(const char* path) { 515 ScopedMount mnt; 516 Path rel; 517 518 Error error = AcquireMountAndRelPath(path, &mnt, &rel); 519 if (error) { 520 errno = error; 521 return -1; 522 } 523 524 error = mnt->Unlink(rel); 525 if (error) { 526 errno = error; 527 return -1; 528 } 529 530 return 0; 531 } 532 533 int KernelProxy::remove(const char* path) { 534 ScopedMount mnt; 535 Path rel; 536 537 Error error = AcquireMountAndRelPath(path, &mnt, &rel); 538 if (error) { 539 errno = error; 540 return -1; 541 } 542 543 error = mnt->Remove(rel); 544 if (error) { 545 errno = error; 546 return -1; 547 } 548 549 return 0; 550 } 551 552 // TODO(noelallen): Needs implementation. 553 int KernelProxy::fchmod(int fd, int mode) { 554 ScopedKernelHandle handle; 555 Error error = AcquireHandle(fd, &handle); 556 if (error) { 557 errno = error; 558 return -1; 559 } 560 561 return 0; 562 } 563 564 int KernelProxy::access(const char* path, int amode) { 565 ScopedMount mnt; 566 Path rel; 567 568 Error error = AcquireMountAndRelPath(path, &mnt, &rel); 569 if (error) { 570 errno = error; 571 return -1; 572 } 573 574 error = mnt->Access(rel, amode); 575 if (error) { 576 errno = error; 577 return -1; 578 } 579 return 0; 580 } 581 582 // TODO(noelallen): Needs implementation. 583 int KernelProxy::link(const char* oldpath, const char* newpath) { 584 errno = EINVAL; 585 return -1; 586 } 587 588 int KernelProxy::symlink(const char* oldpath, const char* newpath) { 589 errno = EINVAL; 590 return -1; 591 } 592 593 void* KernelProxy::mmap(void* addr, 594 size_t length, 595 int prot, 596 int flags, 597 int fd, 598 size_t offset) { 599 // We shouldn't be getting anonymous mmaps here. 600 assert((flags & MAP_ANONYMOUS) == 0); 601 assert(fd != -1); 602 603 ScopedKernelHandle handle; 604 Error error = AcquireHandle(fd, &handle); 605 if (error) { 606 errno = error; 607 return MAP_FAILED; 608 } 609 610 void* new_addr; 611 error = handle->node()->MMap(addr, length, prot, flags, offset, &new_addr); 612 if (error) { 613 errno = error; 614 return MAP_FAILED; 615 } 616 617 return new_addr; 618 } 619 620 int KernelProxy::munmap(void* addr, size_t length) { 621 // NOTE: The comment below is from a previous discarded implementation that 622 // tracks mmap'd regions. For simplicity, we no longer do this; because we 623 // "snapshot" the contents of the file in mmap(), and don't support 624 // write-back or updating the mapped region when the file is written, holding 625 // on to the KernelHandle is pointless. 626 // 627 // If we ever do, these threading issues should be considered. 628 629 // 630 // WARNING: this function may be called by free(). 631 // 632 // There is a potential deadlock scenario: 633 // Thread 1: open() -> takes lock1 -> free() -> takes lock2 634 // Thread 2: free() -> takes lock2 -> munmap() -> takes lock1 635 // 636 // Note that open() above could be any function that takes a lock that is 637 // shared with munmap (this includes munmap!) 638 // 639 // To prevent this, we avoid taking locks in munmap() that are used by other 640 // nacl_io functions that may call free. Specifically, we only take the 641 // mmap_lock, which is only shared with mmap() above. There is still a 642 // possibility of deadlock if mmap() or munmap() calls free(), so this is not 643 // allowed. 644 // 645 // Unfortunately, munmap still needs to acquire other locks; see the call to 646 // ReleaseHandle below which takes the process lock. This is safe as long as 647 // this is never executed from free() -- we can be reasonably sure this is 648 // true, because malloc only makes anonymous mmap() requests, and should only 649 // be munmapping those allocations. We never add to mmap_info_list_ for 650 // anonymous maps, so the unmap_list should always be empty when called from 651 // free(). 652 return 0; 653 } 654 655 int KernelProxy::tcflush(int fd, int queue_selector) { 656 ScopedKernelHandle handle; 657 Error error = AcquireHandle(fd, &handle); 658 if (error) { 659 errno = error; 660 return -1; 661 } 662 663 error = handle->node()->Tcflush(queue_selector); 664 if (error) { 665 errno = error; 666 return -1; 667 } 668 669 return 0; 670 } 671 672 int KernelProxy::tcgetattr(int fd, struct termios* termios_p) { 673 ScopedKernelHandle handle; 674 Error error = AcquireHandle(fd, &handle); 675 if (error) { 676 errno = error; 677 return -1; 678 } 679 680 error = handle->node()->Tcgetattr(termios_p); 681 if (error) { 682 errno = error; 683 return -1; 684 } 685 686 return 0; 687 } 688 689 int KernelProxy::tcsetattr(int fd, int optional_actions, 690 const struct termios *termios_p) { 691 ScopedKernelHandle handle; 692 Error error = AcquireHandle(fd, &handle); 693 if (error) { 694 errno = error; 695 return -1; 696 } 697 698 error = handle->node()->Tcsetattr(optional_actions, termios_p); 699 if (error) { 700 errno = error; 701 return -1; 702 } 703 704 return 0; 705 } 706 707 #ifdef PROVIDES_SOCKET_API 708 709 int KernelProxy::select(int nfds, fd_set* readfds, fd_set* writefds, 710 fd_set* exceptfds, struct timeval* timeout) { 711 ScopedEventListener listener(new EventListener); 712 std::vector<struct pollfd> fds; 713 714 fd_set readout, writeout, exceptout; 715 716 FD_ZERO(&readout); 717 FD_ZERO(&writeout); 718 FD_ZERO(&exceptout); 719 720 int fd; 721 size_t event_cnt = 0; 722 int event_track = 0; 723 for (fd = 0; fd < nfds; fd++) { 724 int events = 0; 725 726 if (readfds != NULL && FD_ISSET(fd, readfds)) 727 events |= POLLIN; 728 729 if (writefds != NULL && FD_ISSET(fd, writefds)) 730 events |= POLLOUT; 731 732 if (exceptfds != NULL && FD_ISSET(fd, exceptfds)) 733 events |= POLLERR | POLLHUP; 734 735 // If we are not interested in this FD, skip it 736 if (0 == events) continue; 737 738 ScopedKernelHandle handle; 739 Error err = AcquireHandle(fd, &handle); 740 741 // Select will return immediately if there are bad FDs. 742 if (err != 0) { 743 errno = EBADF; 744 return -1; 745 } 746 747 int status = handle->node()->GetEventStatus() & events; 748 if (status & POLLIN) { 749 FD_SET(fd, &readout); 750 event_cnt++; 751 } 752 753 if (status & POLLOUT) { 754 FD_SET(fd, &writeout); 755 event_cnt++; 756 } 757 758 if (status & (POLLERR | POLLHUP)) { 759 FD_SET(fd, &exceptout); 760 event_cnt++; 761 } 762 763 // Otherwise track it. 764 if (0 == status) { 765 err = listener->Track(fd, handle->node(), events, fd); 766 if (err != 0) { 767 errno = EBADF; 768 return -1; 769 } 770 event_track++; 771 } 772 } 773 774 // If nothing is signaled, then we must wait. 775 if (event_cnt == 0) { 776 std::vector<EventData> events; 777 int ready_cnt; 778 int ms_timeout; 779 780 // NULL timeout signals wait forever. 781 if (timeout == NULL) { 782 ms_timeout = -1; 783 } else { 784 int64_t ms = timeout->tv_sec * 1000 + ((timeout->tv_usec + 500) / 1000); 785 786 // If the timeout is invalid or too long (larger than signed 32 bit). 787 if ((timeout->tv_sec < 0) || (timeout->tv_sec >= (INT_MAX / 1000)) || 788 (timeout->tv_usec < 0) || (timeout->tv_usec >= 1000) || 789 (ms < 0) || (ms >= INT_MAX)) { 790 errno = EINVAL; 791 return -1; 792 } 793 794 ms_timeout = static_cast<int>(ms); 795 } 796 797 events.resize(event_track); 798 listener->Wait(events.data(), event_track, ms_timeout, &ready_cnt); 799 for (fd = 0; static_cast<int>(fd) < ready_cnt; fd++) { 800 if (events[fd].events & POLLIN) { 801 FD_SET(events[fd].user_data, &readout); 802 event_cnt++; 803 } 804 805 if (events[fd].events & POLLOUT) { 806 FD_SET(events[fd].user_data, &writeout); 807 event_cnt++; 808 } 809 810 if (events[fd].events & (POLLERR | POLLHUP)) { 811 FD_SET(events[fd].user_data, &exceptout); 812 event_cnt++; 813 } 814 } 815 } 816 817 // Copy out the results 818 if (readfds != NULL) 819 *readfds = readout; 820 821 if (writefds != NULL) 822 *writefds = writeout; 823 824 if (exceptfds != NULL) 825 *exceptfds = exceptout; 826 827 return event_cnt; 828 } 829 830 int KernelProxy::poll(struct pollfd *fds, nfds_t nfds, int timeout) { 831 ScopedEventListener listener(new EventListener); 832 833 int index; 834 size_t event_cnt = 0; 835 size_t event_track = 0; 836 for (index = 0; static_cast<nfds_t>(index) < nfds; index++) { 837 ScopedKernelHandle handle; 838 struct pollfd* info = &fds[index]; 839 Error err = AcquireHandle(info->fd, &handle); 840 841 // If the node isn't open, or somehow invalid, mark it so. 842 if (err != 0) { 843 info->revents = POLLNVAL; 844 event_cnt++; 845 continue; 846 } 847 848 // If it's already signaled, then just capture the event 849 if (handle->node()->GetEventStatus() & info->events) { 850 info->revents = info->events & handle->node()->GetEventStatus(); 851 event_cnt++; 852 continue; 853 } 854 855 // Otherwise try to track it. 856 err = listener->Track(info->fd, handle->node(), info->events, index); 857 if (err != 0) { 858 info->revents = POLLNVAL; 859 event_cnt++; 860 continue; 861 } 862 event_track++; 863 } 864 865 // If nothing is signaled, then we must wait. 866 if (0 == event_cnt) { 867 std::vector<EventData> events; 868 int ready_cnt; 869 870 events.resize(event_track); 871 listener->Wait(events.data(), event_track, timeout, &ready_cnt); 872 for (index = 0; index < ready_cnt; index++) { 873 struct pollfd* info = &fds[events[index].user_data]; 874 875 info->revents = events[index].events; 876 event_cnt++; 877 } 878 } 879 880 return event_cnt; 881 } 882 883 884 885 // Socket Functions 886 int KernelProxy::accept(int fd, struct sockaddr* addr, socklen_t* len) { 887 if (NULL == addr || NULL == len) { 888 errno = EFAULT; 889 return -1; 890 } 891 892 ScopedKernelHandle handle; 893 if (AcquireSocketHandle(fd, &handle) == -1) 894 return -1; 895 896 errno = EINVAL; 897 return -1; 898 } 899 900 int KernelProxy::bind(int fd, const struct sockaddr* addr, socklen_t len) { 901 if (NULL == addr) { 902 errno = EFAULT; 903 return -1; 904 } 905 906 ScopedKernelHandle handle; 907 if (AcquireSocketHandle(fd, &handle) == -1) 908 return -1; 909 910 errno = EINVAL; 911 return -1; 912 } 913 914 int KernelProxy::connect(int fd, const struct sockaddr* addr, socklen_t len) { 915 if (NULL == addr) { 916 errno = EFAULT; 917 return -1; 918 } 919 920 ScopedKernelHandle handle; 921 if (AcquireSocketHandle(fd, &handle) == -1) 922 return -1; 923 924 errno = EACCES; 925 return -1; 926 } 927 928 struct hostent* KernelProxy::gethostbyname(const char* name) { 929 return host_resolver_.gethostbyname(name); 930 } 931 932 int KernelProxy::getpeername(int fd, struct sockaddr* addr, socklen_t* len) { 933 if (NULL == addr || NULL == len) { 934 errno = EFAULT; 935 return -1; 936 } 937 938 ScopedKernelHandle handle; 939 if (AcquireSocketHandle(fd, &handle) == -1) 940 return -1; 941 942 errno = EINVAL; 943 return -1; 944 } 945 946 int KernelProxy::getsockname(int fd, struct sockaddr* addr, socklen_t* len) { 947 if (NULL == addr || NULL == len) { 948 errno = EFAULT; 949 return -1; 950 } 951 952 ScopedKernelHandle handle; 953 if (AcquireSocketHandle(fd, &handle) == -1) 954 return -1; 955 956 errno = EINVAL; 957 return -1; 958 } 959 960 int KernelProxy::getsockopt(int fd, 961 int lvl, 962 int optname, 963 void* optval, 964 socklen_t* len) { 965 if (NULL == optval || NULL == len) { 966 errno = EFAULT; 967 return -1; 968 } 969 970 ScopedKernelHandle handle; 971 if (AcquireSocketHandle(fd, &handle) == -1) 972 return -1; 973 974 errno = EINVAL; 975 return -1; 976 } 977 978 int KernelProxy::listen(int fd, int backlog) { 979 ScopedKernelHandle handle; 980 if (AcquireSocketHandle(fd, &handle) == -1) 981 return -1; 982 983 errno = EOPNOTSUPP; 984 return -1; 985 } 986 987 ssize_t KernelProxy::recv(int fd, 988 void* buf, 989 size_t len, 990 int flags) { 991 if (NULL == buf) { 992 errno = EFAULT; 993 return -1; 994 } 995 996 ScopedKernelHandle handle; 997 if (AcquireSocketHandle(fd, &handle) == -1) 998 return -1; 999 1000 errno = EINVAL; 1001 return -1; 1002 } 1003 1004 ssize_t KernelProxy::recvfrom(int fd, 1005 void* buf, 1006 size_t len, 1007 int flags, 1008 struct sockaddr* addr, 1009 socklen_t* addrlen) { 1010 // According to the manpage, recvfrom with a null addr is identical to recv. 1011 if (NULL == addr) { 1012 return recv(fd, buf, len, flags); 1013 } 1014 1015 if (NULL == buf || NULL == addrlen) { 1016 errno = EFAULT; 1017 return -1; 1018 } 1019 1020 ScopedKernelHandle handle; 1021 if (AcquireSocketHandle(fd, &handle) == -1) 1022 return -1; 1023 1024 errno = EINVAL; 1025 return -1; 1026 } 1027 1028 ssize_t KernelProxy::recvmsg(int fd, struct msghdr* msg, int flags) { 1029 if (NULL == msg ) { 1030 errno = EFAULT; 1031 return -1; 1032 } 1033 1034 ScopedKernelHandle handle; 1035 if (AcquireSocketHandle(fd, &handle) == -1) 1036 return -1; 1037 1038 errno = EOPNOTSUPP; 1039 return -1; 1040 } 1041 1042 ssize_t KernelProxy::send(int fd, const void* buf, size_t len, int flags) { 1043 if (NULL == buf) { 1044 errno = EFAULT; 1045 return -1; 1046 } 1047 1048 ScopedKernelHandle handle; 1049 if (AcquireSocketHandle(fd, &handle) == -1) 1050 return -1; 1051 1052 errno = EINVAL; 1053 return -1; 1054 } 1055 1056 ssize_t KernelProxy::sendto(int fd, 1057 const void* buf, 1058 size_t len, 1059 int flags, 1060 const struct sockaddr* addr, 1061 socklen_t addrlen) { 1062 // According to the manpage, sendto with a null addr is identical to send. 1063 if (NULL == addr) { 1064 return send(fd, buf, len, flags); 1065 } 1066 1067 if (NULL == buf) { 1068 errno = EFAULT; 1069 return -1; 1070 } 1071 1072 ScopedKernelHandle handle; 1073 if (AcquireSocketHandle(fd, &handle) == -1) 1074 return -1; 1075 1076 errno = EINVAL; 1077 return -1; 1078 } 1079 1080 ssize_t KernelProxy::sendmsg(int fd, const struct msghdr* msg, int flags) { 1081 if (NULL == msg) { 1082 errno = EFAULT; 1083 return -1; 1084 } 1085 1086 ScopedKernelHandle handle; 1087 if (AcquireSocketHandle(fd, &handle) == -1) 1088 return -1; 1089 1090 errno = EOPNOTSUPP; 1091 return -1; 1092 } 1093 1094 int KernelProxy::setsockopt(int fd, 1095 int lvl, 1096 int optname, 1097 const void* optval, 1098 socklen_t len) { 1099 if (NULL == optval) { 1100 errno = EFAULT; 1101 return -1; 1102 } 1103 1104 ScopedKernelHandle handle; 1105 if (AcquireSocketHandle(fd, &handle) == -1) 1106 return -1; 1107 1108 errno = EINVAL; 1109 return -1; 1110 } 1111 1112 int KernelProxy::shutdown(int fd, int how) { 1113 ScopedKernelHandle handle; 1114 if (AcquireSocketHandle(fd, &handle) == -1) 1115 return -1; 1116 1117 errno = EINVAL; 1118 return -1; 1119 } 1120 1121 int KernelProxy::socket(int domain, int type, int protocol) { 1122 if (AF_INET != domain && AF_INET6 != domain) { 1123 errno = EAFNOSUPPORT; 1124 return -1; 1125 } 1126 1127 if (SOCK_STREAM != type && SOCK_DGRAM != type) { 1128 errno = EPROTONOSUPPORT; 1129 return -1; 1130 } 1131 1132 errno = EACCES; 1133 return -1; 1134 } 1135 1136 int KernelProxy::socketpair(int domain, int type, int protocol, int* sv) { 1137 if (NULL == sv) { 1138 errno = EFAULT; 1139 return -1; 1140 } 1141 1142 // Catch-22: We don't support AF_UNIX, but any other AF doesn't support 1143 // socket pairs. Thus, this function always fails. 1144 if (AF_UNIX != domain) { 1145 errno = EPROTONOSUPPORT; 1146 return -1; 1147 } 1148 1149 if (AF_INET != domain && AF_INET6 != domain) { 1150 errno = EAFNOSUPPORT; 1151 return -1; 1152 } 1153 1154 // We cannot reach this point. 1155 errno = ENOSYS; 1156 return -1; 1157 } 1158 1159 int KernelProxy::AcquireSocketHandle(int fd, ScopedKernelHandle* handle) { 1160 Error error = AcquireHandle(fd, handle); 1161 1162 if (error) { 1163 errno = error; 1164 return -1; 1165 } 1166 1167 if ((handle->get()->node_->GetType() & S_IFSOCK) == 0) { 1168 errno = ENOTSOCK; 1169 return -1; 1170 } 1171 1172 return 0; 1173 } 1174 1175 #endif // PROVIDES_SOCKET_API 1176 1177 } // namespace_nacl_io 1178