| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "nacl_io/kernel_proxy.h" | 5 #include "nacl_io/kernel_proxy.h" |
| 6 | 6 |
| 7 | 7 |
| 8 #include <assert.h> | 8 #include <assert.h> |
| 9 #include <errno.h> | 9 #include <errno.h> |
| 10 #include <fcntl.h> | 10 #include <fcntl.h> |
| 11 #include <limits.h> | 11 #include <limits.h> |
| 12 #include <poll.h> | 12 #include <poll.h> |
| 13 #include <pthread.h> | 13 #include <pthread.h> |
| 14 #include <stdio.h> | 14 #include <stdio.h> |
| 15 #include <string.h> | 15 #include <string.h> |
| 16 #include <sys/time.h> | 16 #include <sys/time.h> |
| 17 #include <unistd.h> | 17 #include <unistd.h> |
| 18 | 18 |
| 19 #include <iterator> | 19 #include <iterator> |
| 20 #include <string> | 20 #include <string> |
| 21 | 21 |
| 22 #include "nacl_io/dbgprint.h" |
| 22 #include "nacl_io/host_resolver.h" | 23 #include "nacl_io/host_resolver.h" |
| 23 #include "nacl_io/kernel_handle.h" | 24 #include "nacl_io/kernel_handle.h" |
| 24 #include "nacl_io/kernel_wrap_real.h" | 25 #include "nacl_io/kernel_wrap_real.h" |
| 25 #include "nacl_io/mount.h" | 26 #include "nacl_io/mount.h" |
| 26 #include "nacl_io/mount_dev.h" | 27 #include "nacl_io/mount_dev.h" |
| 27 #include "nacl_io/mount_html5fs.h" | 28 #include "nacl_io/mount_html5fs.h" |
| 28 #include "nacl_io/mount_http.h" | 29 #include "nacl_io/mount_http.h" |
| 29 #include "nacl_io/mount_mem.h" | 30 #include "nacl_io/mount_mem.h" |
| 30 #include "nacl_io/mount_node.h" | 31 #include "nacl_io/mount_node.h" |
| 31 #include "nacl_io/mount_node_tcp.h" | 32 #include "nacl_io/mount_node_tcp.h" |
| 32 #include "nacl_io/mount_node_udp.h" | 33 #include "nacl_io/mount_node_udp.h" |
| 33 #include "nacl_io/mount_passthrough.h" | 34 #include "nacl_io/mount_passthrough.h" |
| 34 #include "nacl_io/osmman.h" | 35 #include "nacl_io/osmman.h" |
| 35 #include "nacl_io/ossocket.h" | 36 #include "nacl_io/ossocket.h" |
| 36 #include "nacl_io/osstat.h" | 37 #include "nacl_io/osstat.h" |
| 37 #include "nacl_io/path.h" | 38 #include "nacl_io/path.h" |
| 38 #include "nacl_io/pepper_interface.h" | 39 #include "nacl_io/pepper_interface.h" |
| 39 #include "nacl_io/typed_mount_factory.h" | 40 #include "nacl_io/typed_mount_factory.h" |
| 40 #include "sdk_util/auto_lock.h" | 41 #include "sdk_util/auto_lock.h" |
| 41 #include "sdk_util/ref_object.h" | 42 #include "sdk_util/ref_object.h" |
| 42 | 43 |
| 43 #ifndef MAXPATHLEN | 44 #ifndef MAXPATHLEN |
| 44 #define MAXPATHLEN 256 | 45 #define MAXPATHLEN 256 |
| 45 #endif | 46 #endif |
| 46 | 47 |
| 47 namespace nacl_io { | 48 namespace nacl_io { |
| 48 | 49 |
| 49 KernelProxy::KernelProxy() : dev_(0), ppapi_(NULL) { | 50 class SignalEmitter : public EventEmitter { |
| 51 public: |
| 52 // From EventEmitter. The SignalEmitter exists in order |
| 53 // to inturrupt anything waiting in select()/poll() when kill() |
| 54 // is called. It is an edge trigger only and therefore has no |
| 55 // persistent readable/wriable/error state. |
| 56 uint32_t GetEventStatus() { |
| 57 return 0; |
| 58 } |
| 59 |
| 60 int GetType() { |
| 61 // For lack of a better type, report socket to signify it can be in an |
| 62 // used to signal. |
| 63 return S_IFSOCK; |
| 64 } |
| 65 |
| 66 void SignalOccurred() { |
| 67 RaiseEvent(POLLERR); |
| 68 } |
| 69 }; |
| 70 |
| 71 KernelProxy::KernelProxy() : dev_(0), ppapi_(NULL), |
| 72 sigwinch_handler_(SIG_IGN), |
| 73 signal_emitter_(new SignalEmitter) { |
| 74 |
| 50 } | 75 } |
| 51 | 76 |
| 52 KernelProxy::~KernelProxy() { | 77 KernelProxy::~KernelProxy() { |
| 53 // Clean up the MountFactories. | 78 // Clean up the MountFactories. |
| 54 for (MountFactoryMap_t::iterator i = factories_.begin(); | 79 for (MountFactoryMap_t::iterator i = factories_.begin(); |
| 55 i != factories_.end(); | 80 i != factories_.end(); |
| 56 ++i) { | 81 ++i) { |
| 57 delete i->second; | 82 delete i->second; |
| 58 } | 83 } |
| 59 | 84 |
| (...skipping 645 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 705 error = handle->node()->Tcsetattr(optional_actions, termios_p); | 730 error = handle->node()->Tcsetattr(optional_actions, termios_p); |
| 706 if (error) { | 731 if (error) { |
| 707 errno = error; | 732 errno = error; |
| 708 return -1; | 733 return -1; |
| 709 } | 734 } |
| 710 | 735 |
| 711 return 0; | 736 return 0; |
| 712 } | 737 } |
| 713 | 738 |
| 714 int KernelProxy::kill(pid_t pid, int sig) { | 739 int KernelProxy::kill(pid_t pid, int sig) { |
| 715 errno = EINVAL; | 740 // Currently we don't even pretend that other processes exist |
| 716 return -1; | 741 // so we can only send a signal to outselves. For kill(2) |
| 742 // pid 0 means the current process group and -1 means all the |
| 743 // processes we have permission to send signals to. |
| 744 if (pid != getpid() && pid != -1 && pid != 0) { |
| 745 errno = ESRCH; |
| 746 return -1; |
| 747 } |
| 748 |
| 749 // Raise an event so that select/poll get interrupted. |
| 750 signal_emitter_->SignalOccurred(); |
| 751 switch (sig) { |
| 752 case SIGWINCH: |
| 753 if (sigwinch_handler_ != SIG_IGN) |
| 754 sigwinch_handler_(SIGWINCH); |
| 755 break; |
| 756 |
| 757 case SIGUSR1: |
| 758 case SIGUSR2: |
| 759 break; |
| 760 |
| 761 default: |
| 762 errno = EINVAL; |
| 763 return -1; |
| 764 } |
| 765 |
| 766 return 0; |
| 717 } | 767 } |
| 718 | 768 |
| 719 sighandler_t KernelProxy::sigset(int signum, sighandler_t handler) { | 769 sighandler_t KernelProxy::sigset(int signum, sighandler_t handler) { |
| 770 switch (signum) { |
| 771 // Handled signals. |
| 772 case SIGWINCH: { |
| 773 sighandler_t old_value = sigwinch_handler_; |
| 774 if (handler == SIG_DFL) |
| 775 handler = SIG_IGN; |
| 776 sigwinch_handler_ = handler; |
| 777 return old_value; |
| 778 } |
| 779 |
| 780 // Known signals |
| 781 case SIGHUP: |
| 782 case SIGINT: |
| 783 case SIGKILL: |
| 784 case SIGPIPE: |
| 785 case SIGPOLL: |
| 786 case SIGPROF: |
| 787 case SIGTERM: |
| 788 case SIGCHLD: |
| 789 case SIGURG: |
| 790 case SIGFPE: |
| 791 case SIGILL: |
| 792 case SIGQUIT: |
| 793 case SIGSEGV: |
| 794 case SIGTRAP: |
| 795 if (handler == SIG_DFL) |
| 796 return SIG_DFL; |
| 797 break; |
| 798 } |
| 799 |
| 720 errno = EINVAL; | 800 errno = EINVAL; |
| 721 return SIG_ERR; | 801 return SIG_ERR; |
| 722 } | 802 } |
| 723 | 803 |
| 724 #ifdef PROVIDES_SOCKET_API | 804 #ifdef PROVIDES_SOCKET_API |
| 725 | 805 |
| 726 int KernelProxy::select(int nfds, fd_set* readfds, fd_set* writefds, | 806 int KernelProxy::select(int nfds, fd_set* readfds, fd_set* writefds, |
| 727 fd_set* exceptfds, struct timeval* timeout) { | 807 fd_set* exceptfds, struct timeval* timeout) { |
| 728 ScopedEventListener listener(new EventListener); | 808 ScopedEventListener listener(new EventListener); |
| 809 |
| 729 std::vector<struct pollfd> fds; | 810 std::vector<struct pollfd> fds; |
| 730 | 811 |
| 731 fd_set readout, writeout, exceptout; | 812 fd_set readout, writeout, exceptout; |
| 732 | 813 |
| 733 FD_ZERO(&readout); | 814 FD_ZERO(&readout); |
| 734 FD_ZERO(&writeout); | 815 FD_ZERO(&writeout); |
| 735 FD_ZERO(&exceptout); | 816 FD_ZERO(&exceptout); |
| 736 | 817 |
| 737 int fd; | 818 int fd; |
| 738 size_t event_cnt = 0; | 819 size_t event_cnt = 0; |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 804 if ((timeout->tv_sec < 0) || (timeout->tv_sec >= (INT_MAX / 1000)) || | 885 if ((timeout->tv_sec < 0) || (timeout->tv_sec >= (INT_MAX / 1000)) || |
| 805 (timeout->tv_usec < 0) || (timeout->tv_usec >= 1000000) || | 886 (timeout->tv_usec < 0) || (timeout->tv_usec >= 1000000) || |
| 806 (ms < 0) || (ms >= INT_MAX)) { | 887 (ms < 0) || (ms >= INT_MAX)) { |
| 807 errno = EINVAL; | 888 errno = EINVAL; |
| 808 return -1; | 889 return -1; |
| 809 } | 890 } |
| 810 | 891 |
| 811 ms_timeout = static_cast<int>(ms); | 892 ms_timeout = static_cast<int>(ms); |
| 812 } | 893 } |
| 813 | 894 |
| 895 // Add a special node to listen for events |
| 896 // coming from the KernelProxy itself (kill will |
| 897 // generated a SIGERR event). |
| 898 listener->Track(-1, signal_emitter_, POLLERR, -1); |
| 899 event_track += 1; |
| 900 |
| 814 events.resize(event_track); | 901 events.resize(event_track); |
| 902 |
| 903 bool interrupted = false; |
| 815 listener->Wait(events.data(), event_track, ms_timeout, &ready_cnt); | 904 listener->Wait(events.data(), event_track, ms_timeout, &ready_cnt); |
| 816 for (fd = 0; static_cast<int>(fd) < ready_cnt; fd++) { | 905 for (fd = 0; static_cast<int>(fd) < ready_cnt; fd++) { |
| 906 if (events[fd].user_data == static_cast<uint64_t>(-1)) { |
| 907 if (events[fd].events & POLLERR) { |
| 908 interrupted = true; |
| 909 } |
| 910 continue; |
| 911 } |
| 912 |
| 817 if (events[fd].events & POLLIN) { | 913 if (events[fd].events & POLLIN) { |
| 818 FD_SET(events[fd].user_data, &readout); | 914 FD_SET(events[fd].user_data, &readout); |
| 819 event_cnt++; | 915 event_cnt++; |
| 820 } | 916 } |
| 821 | 917 |
| 822 if (events[fd].events & POLLOUT) { | 918 if (events[fd].events & POLLOUT) { |
| 823 FD_SET(events[fd].user_data, &writeout); | 919 FD_SET(events[fd].user_data, &writeout); |
| 824 event_cnt++; | 920 event_cnt++; |
| 825 } | 921 } |
| 826 | 922 |
| 827 if (events[fd].events & (POLLERR | POLLHUP)) { | 923 if (events[fd].events & (POLLERR | POLLHUP)) { |
| 828 FD_SET(events[fd].user_data, &exceptout); | 924 FD_SET(events[fd].user_data, &exceptout); |
| 829 event_cnt++; | 925 event_cnt++; |
| 830 } | 926 } |
| 831 } | 927 } |
| 928 |
| 929 if (0 == event_cnt && interrupted) { |
| 930 errno = EINTR; |
| 931 return -1; |
| 932 } |
| 832 } | 933 } |
| 833 | 934 |
| 834 // Copy out the results | 935 // Copy out the results |
| 835 if (readfds != NULL) | 936 if (readfds != NULL) |
| 836 *readfds = readout; | 937 *readfds = readout; |
| 837 | 938 |
| 838 if (writefds != NULL) | 939 if (writefds != NULL) |
| 839 *writefds = writeout; | 940 *writefds = writeout; |
| 840 | 941 |
| 841 if (exceptfds != NULL) | 942 if (exceptfds != NULL) |
| 842 *exceptfds = exceptout; | 943 *exceptfds = exceptout; |
| 843 | 944 |
| 844 return event_cnt; | 945 return event_cnt; |
| 845 } | 946 } |
| 846 | 947 |
| 847 int KernelProxy::poll(struct pollfd *fds, nfds_t nfds, int timeout) { | 948 int KernelProxy::poll(struct pollfd *fds, nfds_t nfds, int timeout) { |
| 848 ScopedEventListener listener(new EventListener); | 949 ScopedEventListener listener(new EventListener); |
| 950 listener->Track(-1, signal_emitter_, POLLERR, 0); |
| 849 | 951 |
| 850 int index; | 952 int index; |
| 851 size_t event_cnt = 0; | 953 size_t event_cnt = 0; |
| 852 size_t event_track = 0; | 954 size_t event_track = 1; |
| 853 for (index = 0; static_cast<nfds_t>(index) < nfds; index++) { | 955 for (index = 0; static_cast<nfds_t>(index) < nfds; index++) { |
| 854 ScopedKernelHandle handle; | 956 ScopedKernelHandle handle; |
| 855 struct pollfd* info = &fds[index]; | 957 struct pollfd* info = &fds[index]; |
| 856 Error err = AcquireHandle(info->fd, &handle); | 958 Error err = AcquireHandle(info->fd, &handle); |
| 857 | 959 |
| 858 // If the node isn't open, or somehow invalid, mark it so. | 960 // If the node isn't open, or somehow invalid, mark it so. |
| 859 if (err != 0) { | 961 if (err != 0) { |
| 860 info->revents = POLLNVAL; | 962 info->revents = POLLNVAL; |
| 861 event_cnt++; | 963 event_cnt++; |
| 862 continue; | 964 continue; |
| (...skipping 14 matching lines...) Expand all Loading... |
| 877 continue; | 979 continue; |
| 878 } | 980 } |
| 879 event_track++; | 981 event_track++; |
| 880 } | 982 } |
| 881 | 983 |
| 882 // If nothing is signaled, then we must wait. | 984 // If nothing is signaled, then we must wait. |
| 883 if (0 == event_cnt) { | 985 if (0 == event_cnt) { |
| 884 std::vector<EventData> events; | 986 std::vector<EventData> events; |
| 885 int ready_cnt; | 987 int ready_cnt; |
| 886 | 988 |
| 989 bool interrupted = false; |
| 887 events.resize(event_track); | 990 events.resize(event_track); |
| 888 listener->Wait(events.data(), event_track, timeout, &ready_cnt); | 991 listener->Wait(events.data(), event_track, timeout, &ready_cnt); |
| 889 for (index = 0; index < ready_cnt; index++) { | 992 for (index = 0; index < ready_cnt; index++) { |
| 890 struct pollfd* info = &fds[events[index].user_data]; | 993 struct pollfd* info = &fds[events[index].user_data]; |
| 994 if (!info) { |
| 995 interrupted = true; |
| 996 continue; |
| 997 } |
| 891 | 998 |
| 892 info->revents = events[index].events; | 999 info->revents = events[index].events; |
| 893 event_cnt++; | 1000 event_cnt++; |
| 894 } | 1001 } |
| 1002 if (0 == event_cnt && interrupted) { |
| 1003 errno = EINTR; |
| 1004 return -1; |
| 1005 } |
| 895 } | 1006 } |
| 896 | 1007 |
| 897 return event_cnt; | 1008 return event_cnt; |
| 898 } | 1009 } |
| 899 | 1010 |
| 900 | 1011 |
| 901 | 1012 |
| 902 // Socket Functions | 1013 // Socket Functions |
| 903 int KernelProxy::accept(int fd, struct sockaddr* addr, socklen_t* len) { | 1014 int KernelProxy::accept(int fd, struct sockaddr* addr, socklen_t* len) { |
| 904 if (NULL == addr || NULL == len) { | 1015 if (NULL == addr || NULL == len) { |
| (...skipping 352 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1257 errno = ENOTSOCK; | 1368 errno = ENOTSOCK; |
| 1258 return -1; | 1369 return -1; |
| 1259 } | 1370 } |
| 1260 | 1371 |
| 1261 return 0; | 1372 return 0; |
| 1262 } | 1373 } |
| 1263 | 1374 |
| 1264 #endif // PROVIDES_SOCKET_API | 1375 #endif // PROVIDES_SOCKET_API |
| 1265 | 1376 |
| 1266 } // namespace_nacl_io | 1377 } // namespace_nacl_io |
| OLD | NEW |