| 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> |
| (...skipping 11 matching lines...) Expand all Loading... |
| 22 #include "nacl_io/dbgprint.h" | 22 #include "nacl_io/dbgprint.h" |
| 23 #include "nacl_io/host_resolver.h" | 23 #include "nacl_io/host_resolver.h" |
| 24 #include "nacl_io/kernel_handle.h" | 24 #include "nacl_io/kernel_handle.h" |
| 25 #include "nacl_io/kernel_wrap_real.h" | 25 #include "nacl_io/kernel_wrap_real.h" |
| 26 #include "nacl_io/mount.h" | 26 #include "nacl_io/mount.h" |
| 27 #include "nacl_io/mount_dev.h" | 27 #include "nacl_io/mount_dev.h" |
| 28 #include "nacl_io/mount_html5fs.h" | 28 #include "nacl_io/mount_html5fs.h" |
| 29 #include "nacl_io/mount_http.h" | 29 #include "nacl_io/mount_http.h" |
| 30 #include "nacl_io/mount_mem.h" | 30 #include "nacl_io/mount_mem.h" |
| 31 #include "nacl_io/mount_node.h" | 31 #include "nacl_io/mount_node.h" |
| 32 #include "nacl_io/mount_node_pipe.h" |
| 32 #include "nacl_io/mount_node_tcp.h" | 33 #include "nacl_io/mount_node_tcp.h" |
| 33 #include "nacl_io/mount_node_udp.h" | 34 #include "nacl_io/mount_node_udp.h" |
| 34 #include "nacl_io/mount_passthrough.h" | 35 #include "nacl_io/mount_passthrough.h" |
| 36 #include "nacl_io/mount_stream.h" |
| 35 #include "nacl_io/osmman.h" | 37 #include "nacl_io/osmman.h" |
| 36 #include "nacl_io/ossocket.h" | 38 #include "nacl_io/ossocket.h" |
| 37 #include "nacl_io/osstat.h" | 39 #include "nacl_io/osstat.h" |
| 38 #include "nacl_io/path.h" | 40 #include "nacl_io/path.h" |
| 39 #include "nacl_io/pepper_interface.h" | 41 #include "nacl_io/pepper_interface.h" |
| 40 #include "nacl_io/typed_mount_factory.h" | 42 #include "nacl_io/typed_mount_factory.h" |
| 41 #include "sdk_util/auto_lock.h" | 43 #include "sdk_util/auto_lock.h" |
| 42 #include "sdk_util/ref_object.h" | 44 #include "sdk_util/ref_object.h" |
| 43 #include "sdk_util/string_util.h" | 45 #include "sdk_util/string_util.h" |
| 44 | 46 |
| 45 #ifndef MAXPATHLEN | 47 #ifndef MAXPATHLEN |
| 46 #define MAXPATHLEN 256 | 48 #define MAXPATHLEN 256 |
| 47 #endif | 49 #endif |
| 48 | 50 |
| 49 namespace nacl_io { | 51 namespace nacl_io { |
| 50 | 52 |
| 51 class SignalEmitter : public EventEmitter { | |
| 52 public: | |
| 53 // From EventEmitter. The SignalEmitter exists in order | |
| 54 // to inturrupt anything waiting in select()/poll() when kill() | |
| 55 // is called. It is an edge trigger only and therefore has no | |
| 56 // persistent readable/wriable/error state. | |
| 57 uint32_t GetEventStatus() { | |
| 58 return 0; | |
| 59 } | |
| 60 | |
| 61 int GetType() { | |
| 62 // For lack of a better type, report socket to signify it can be in an | |
| 63 // used to signal. | |
| 64 return S_IFSOCK; | |
| 65 } | |
| 66 | |
| 67 void SignalOccurred() { | |
| 68 RaiseEvent(POLLERR); | |
| 69 } | |
| 70 }; | |
| 71 | 53 |
| 72 KernelProxy::KernelProxy() : dev_(0), ppapi_(NULL), | 54 KernelProxy::KernelProxy() : dev_(0), ppapi_(NULL), |
| 73 sigwinch_handler_(SIG_IGN), | 55 sigwinch_handler_(SIG_IGN), |
| 74 signal_emitter_(new SignalEmitter) { | 56 signal_emitter_(new EventEmitter) { |
| 75 | 57 |
| 76 } | 58 } |
| 77 | 59 |
| 78 KernelProxy::~KernelProxy() { | 60 KernelProxy::~KernelProxy() { |
| 79 // Clean up the MountFactories. | 61 // Clean up the MountFactories. |
| 80 for (MountFactoryMap_t::iterator i = factories_.begin(); | 62 for (MountFactoryMap_t::iterator i = factories_.begin(); |
| 81 i != factories_.end(); | 63 i != factories_.end(); |
| 82 ++i) { | 64 ++i) { |
| 83 delete i->second; | 65 delete i->second; |
| 84 } | 66 } |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 125 fd = open("/dev/stderr", O_WRONLY); | 107 fd = open("/dev/stderr", O_WRONLY); |
| 126 assert(fd == 2); | 108 assert(fd == 2); |
| 127 if (fd < 0) | 109 if (fd < 0) |
| 128 rtn = errno; | 110 rtn = errno; |
| 129 | 111 |
| 130 #ifdef PROVIDES_SOCKET_API | 112 #ifdef PROVIDES_SOCKET_API |
| 131 host_resolver_.Init(ppapi_); | 113 host_resolver_.Init(ppapi_); |
| 132 #endif | 114 #endif |
| 133 | 115 |
| 134 StringMap_t args; | 116 StringMap_t args; |
| 135 socket_mount_.reset(new MountSocket()); | 117 stream_mount_.reset(new MountStream()); |
| 136 result = socket_mount_->Init(0, args, ppapi); | 118 result = stream_mount_->Init(0, args, ppapi); |
| 137 if (result != 0) { | 119 if (result != 0) { |
| 138 assert(false); | 120 assert(false); |
| 139 rtn = result; | 121 rtn = result; |
| 140 } | 122 } |
| 141 | 123 |
| 142 return rtn; | 124 return rtn; |
| 143 } | 125 } |
| 144 | 126 |
| 145 int KernelProxy::open_resource(const char* path) { | 127 int KernelProxy::open_resource(const char* path) { |
| 146 ScopedMount mnt; | 128 ScopedMount mnt; |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 186 ScopedKernelHandle handle(new KernelHandle(mnt, node)); | 168 ScopedKernelHandle handle(new KernelHandle(mnt, node)); |
| 187 error = handle->Init(oflags); | 169 error = handle->Init(oflags); |
| 188 if (error) { | 170 if (error) { |
| 189 errno = error; | 171 errno = error; |
| 190 return -1; | 172 return -1; |
| 191 } | 173 } |
| 192 | 174 |
| 193 return AllocateFD(handle); | 175 return AllocateFD(handle); |
| 194 } | 176 } |
| 195 | 177 |
| 178 int KernelProxy::pipe(int pipefds[2]) { |
| 179 MountNodePipe* pipe = new MountNodePipe(stream_mount_.get()); |
| 180 ScopedMountNode node(pipe); |
| 181 |
| 182 if (pipe->Init(S_IREAD | S_IWRITE) == 0) { |
| 183 ScopedKernelHandle handle0(new KernelHandle(stream_mount_, node)); |
| 184 ScopedKernelHandle handle1(new KernelHandle(stream_mount_, node)); |
| 185 |
| 186 // Should never fail, but... |
| 187 if (handle0->Init(S_IREAD) || handle1->Init(S_IWRITE)) { |
| 188 errno = EACCES; |
| 189 return -1; |
| 190 } |
| 191 |
| 192 pipefds[0] = AllocateFD(handle0); |
| 193 pipefds[1] = AllocateFD(handle1); |
| 194 return 0; |
| 195 } |
| 196 |
| 197 errno = ENOSYS; |
| 198 return -1; |
| 199 } |
| 200 |
| 196 int KernelProxy::close(int fd) { | 201 int KernelProxy::close(int fd) { |
| 197 ScopedKernelHandle handle; | 202 ScopedKernelHandle handle; |
| 198 Error error = AcquireHandle(fd, &handle); | 203 Error error = AcquireHandle(fd, &handle); |
| 199 if (error) { | 204 if (error) { |
| 200 errno = error; | 205 errno = error; |
| 201 return -1; | 206 return -1; |
| 202 } | 207 } |
| 203 | 208 |
| 204 // Remove the FD from the process open file descriptor map | 209 // Remove the FD from the process open file descriptor map |
| 205 FreeFD(fd); | 210 FreeFD(fd); |
| (...skipping 560 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 766 // Currently we don't even pretend that other processes exist | 771 // Currently we don't even pretend that other processes exist |
| 767 // so we can only send a signal to outselves. For kill(2) | 772 // so we can only send a signal to outselves. For kill(2) |
| 768 // pid 0 means the current process group and -1 means all the | 773 // pid 0 means the current process group and -1 means all the |
| 769 // processes we have permission to send signals to. | 774 // processes we have permission to send signals to. |
| 770 if (pid != getpid() && pid != -1 && pid != 0) { | 775 if (pid != getpid() && pid != -1 && pid != 0) { |
| 771 errno = ESRCH; | 776 errno = ESRCH; |
| 772 return -1; | 777 return -1; |
| 773 } | 778 } |
| 774 | 779 |
| 775 // Raise an event so that select/poll get interrupted. | 780 // Raise an event so that select/poll get interrupted. |
| 776 signal_emitter_->SignalOccurred(); | 781 AUTO_LOCK(signal_emitter_->GetLock()) |
| 782 signal_emitter_->RaiseEvents_Locked(POLLERR); |
| 777 switch (sig) { | 783 switch (sig) { |
| 778 case SIGWINCH: | 784 case SIGWINCH: |
| 779 if (sigwinch_handler_ != SIG_IGN) | 785 if (sigwinch_handler_ != SIG_IGN) |
| 780 sigwinch_handler_(SIGWINCH); | 786 sigwinch_handler_(SIGWINCH); |
| 781 break; | 787 break; |
| 782 | 788 |
| 783 case SIGUSR1: | 789 case SIGUSR1: |
| 784 case SIGUSR2: | 790 case SIGUSR2: |
| 785 break; | 791 break; |
| 786 | 792 |
| 787 default: | 793 default: |
| 788 errno = EINVAL; | 794 errno = EINVAL; |
| 789 return -1; | 795 return -1; |
| 790 } | 796 } |
| 791 | |
| 792 return 0; | 797 return 0; |
| 793 } | 798 } |
| 794 | 799 |
| 795 sighandler_t KernelProxy::sigset(int signum, sighandler_t handler) { | 800 sighandler_t KernelProxy::sigset(int signum, sighandler_t handler) { |
| 796 switch (signum) { | 801 switch (signum) { |
| 797 // Handled signals. | 802 // Handled signals. |
| 798 case SIGWINCH: { | 803 case SIGWINCH: { |
| 799 sighandler_t old_value = sigwinch_handler_; | 804 sighandler_t old_value = sigwinch_handler_; |
| 800 if (handler == SIG_DFL) | 805 if (handler == SIG_DFL) |
| 801 handler = SIG_IGN; | 806 handler = SIG_IGN; |
| (...skipping 22 matching lines...) Expand all Loading... |
| 824 } | 829 } |
| 825 | 830 |
| 826 errno = EINVAL; | 831 errno = EINVAL; |
| 827 return SIG_ERR; | 832 return SIG_ERR; |
| 828 } | 833 } |
| 829 | 834 |
| 830 #ifdef PROVIDES_SOCKET_API | 835 #ifdef PROVIDES_SOCKET_API |
| 831 | 836 |
| 832 int KernelProxy::select(int nfds, fd_set* readfds, fd_set* writefds, | 837 int KernelProxy::select(int nfds, fd_set* readfds, fd_set* writefds, |
| 833 fd_set* exceptfds, struct timeval* timeout) { | 838 fd_set* exceptfds, struct timeval* timeout) { |
| 834 ScopedEventListener listener(new EventListener); | 839 fd_set ignore; |
| 840 std::vector<pollfd> pollfds; |
| 835 | 841 |
| 836 std::vector<struct pollfd> fds; | 842 // Simplify logic, by using an IGNORE set for any undefined set |
| 843 FD_ZERO(&ignore); |
| 844 if (NULL == readfds) |
| 845 readfds = &ignore; |
| 846 if (NULL == writefds) |
| 847 writefds = &ignore; |
| 848 if (NULL == exceptfds) |
| 849 exceptfds = &ignore; |
| 837 | 850 |
| 838 fd_set readout, writeout, exceptout; | 851 for (int fd = 0; fd < nfds; fd++) { |
| 839 | |
| 840 FD_ZERO(&readout); | |
| 841 FD_ZERO(&writeout); | |
| 842 FD_ZERO(&exceptout); | |
| 843 | |
| 844 int fd; | |
| 845 size_t event_cnt = 0; | |
| 846 int event_track = 0; | |
| 847 for (fd = 0; fd < nfds; fd++) { | |
| 848 int events = 0; | 852 int events = 0; |
| 849 | 853 if (FD_ISSET(fd, readfds)) |
| 850 if (readfds != NULL && FD_ISSET(fd, readfds)) | |
| 851 events |= POLLIN; | 854 events |= POLLIN; |
| 852 | 855 |
| 853 if (writefds != NULL && FD_ISSET(fd, writefds)) | 856 if (FD_ISSET(fd, writefds)) |
| 854 events |= POLLOUT; | 857 events |= POLLOUT; |
| 855 | 858 |
| 856 if (exceptfds != NULL && FD_ISSET(fd, exceptfds)) | 859 if (FD_ISSET(fd, exceptfds)) |
| 857 events |= POLLERR | POLLHUP; | 860 events |= POLLERR | POLLHUP; |
| 858 | 861 |
| 859 // If we are not interested in this FD, skip it | 862 if (events) { |
| 860 if (0 == events) continue; | 863 pollfd info; |
| 864 info.fd = fd; |
| 865 info.events = events; |
| 866 pollfds.push_back(info); |
| 867 } |
| 868 } |
| 861 | 869 |
| 862 ScopedKernelHandle handle; | 870 FD_ZERO(readfds); |
| 863 Error err = AcquireHandle(fd, &handle); | 871 FD_ZERO(writefds); |
| 872 FD_ZERO(exceptfds); |
| 864 | 873 |
| 865 // Select will return immediately if there are bad FDs. | 874 // NULL timeout signals wait forever. |
| 866 if (err != 0) { | 875 int ms_timeout = -1; |
| 867 errno = EBADF; | 876 if (timeout != NULL) { |
| 877 int64_t ms = timeout->tv_sec * 1000 + ((timeout->tv_usec + 500) / 1000); |
| 878 |
| 879 // If the timeout is invalid or too long (larger than signed 32 bit). |
| 880 if ((timeout->tv_sec < 0) || (timeout->tv_sec >= (INT_MAX / 1000)) || |
| 881 (timeout->tv_usec < 0) || (timeout->tv_usec >= 1000000) || |
| 882 (ms < 0) || (ms >= INT_MAX)) { |
| 883 errno = EINVAL; |
| 868 return -1; | 884 return -1; |
| 869 } | 885 } |
| 870 | 886 |
| 871 int status = handle->node()->GetEventStatus() & events; | 887 ms_timeout = static_cast<int>(ms); |
| 872 if (status & POLLIN) { | 888 } |
| 873 FD_SET(fd, &readout); | 889 |
| 890 int result = poll(&pollfds[0], pollfds.size(), ms_timeout); |
| 891 if (result == -1) |
| 892 return -1; |
| 893 |
| 894 int event_cnt = 0; |
| 895 for (size_t index = 0; index < pollfds.size(); index++) { |
| 896 pollfd* info = &pollfds[index]; |
| 897 if (info->revents & POLLIN) { |
| 898 FD_SET(info->fd, readfds); |
| 874 event_cnt++; | 899 event_cnt++; |
| 875 } | 900 } |
| 876 | 901 if (info->revents & POLLOUT) { |
| 877 if (status & POLLOUT) { | 902 FD_SET(info->fd, writefds); |
| 878 FD_SET(fd, &writeout); | |
| 879 event_cnt++; | 903 event_cnt++; |
| 880 } | 904 } |
| 881 | 905 if (info->revents & (POLLHUP | POLLERR)) { |
| 882 if (status & (POLLERR | POLLHUP)) { | 906 FD_SET(info->fd, exceptfds); |
| 883 FD_SET(fd, &exceptout); | |
| 884 event_cnt++; | 907 event_cnt++; |
| 885 } | 908 } |
| 886 | |
| 887 // Otherwise track it. | |
| 888 if (0 == status) { | |
| 889 err = listener->Track(fd, handle->node(), events, fd); | |
| 890 if (err != 0) { | |
| 891 errno = EBADF; | |
| 892 return -1; | |
| 893 } | |
| 894 event_track++; | |
| 895 } | |
| 896 } | 909 } |
| 897 | 910 |
| 898 // If nothing is signaled, then we must wait. | |
| 899 if (event_cnt == 0) { | |
| 900 std::vector<EventData> events; | |
| 901 int ready_cnt; | |
| 902 int ms_timeout; | |
| 903 | |
| 904 // NULL timeout signals wait forever. | |
| 905 if (timeout == NULL) { | |
| 906 ms_timeout = -1; | |
| 907 } else { | |
| 908 int64_t ms = timeout->tv_sec * 1000 + ((timeout->tv_usec + 500) / 1000); | |
| 909 | |
| 910 // If the timeout is invalid or too long (larger than signed 32 bit). | |
| 911 if ((timeout->tv_sec < 0) || (timeout->tv_sec >= (INT_MAX / 1000)) || | |
| 912 (timeout->tv_usec < 0) || (timeout->tv_usec >= 1000000) || | |
| 913 (ms < 0) || (ms >= INT_MAX)) { | |
| 914 errno = EINVAL; | |
| 915 return -1; | |
| 916 } | |
| 917 | |
| 918 ms_timeout = static_cast<int>(ms); | |
| 919 } | |
| 920 | |
| 921 // Add a special node to listen for events | |
| 922 // coming from the KernelProxy itself (kill will | |
| 923 // generated a SIGERR event). | |
| 924 listener->Track(-1, signal_emitter_, POLLERR, -1); | |
| 925 event_track += 1; | |
| 926 | |
| 927 events.resize(event_track); | |
| 928 | |
| 929 bool interrupted = false; | |
| 930 listener->Wait(events.data(), event_track, ms_timeout, &ready_cnt); | |
| 931 for (fd = 0; static_cast<int>(fd) < ready_cnt; fd++) { | |
| 932 if (events[fd].user_data == static_cast<uint64_t>(-1)) { | |
| 933 if (events[fd].events & POLLERR) { | |
| 934 interrupted = true; | |
| 935 } | |
| 936 continue; | |
| 937 } | |
| 938 | |
| 939 if (events[fd].events & POLLIN) { | |
| 940 FD_SET(events[fd].user_data, &readout); | |
| 941 event_cnt++; | |
| 942 } | |
| 943 | |
| 944 if (events[fd].events & POLLOUT) { | |
| 945 FD_SET(events[fd].user_data, &writeout); | |
| 946 event_cnt++; | |
| 947 } | |
| 948 | |
| 949 if (events[fd].events & (POLLERR | POLLHUP)) { | |
| 950 FD_SET(events[fd].user_data, &exceptout); | |
| 951 event_cnt++; | |
| 952 } | |
| 953 } | |
| 954 | |
| 955 if (0 == event_cnt && interrupted) { | |
| 956 errno = EINTR; | |
| 957 return -1; | |
| 958 } | |
| 959 } | |
| 960 | |
| 961 // Copy out the results | |
| 962 if (readfds != NULL) | |
| 963 *readfds = readout; | |
| 964 | |
| 965 if (writefds != NULL) | |
| 966 *writefds = writeout; | |
| 967 | |
| 968 if (exceptfds != NULL) | |
| 969 *exceptfds = exceptout; | |
| 970 | |
| 971 return event_cnt; | 911 return event_cnt; |
| 972 } | 912 } |
| 973 | 913 |
| 914 struct PollInfo { |
| 915 PollInfo() : index(-1) {}; |
| 916 |
| 917 std::vector<struct pollfd*> fds; |
| 918 int index; |
| 919 }; |
| 920 |
| 921 typedef std::map<EventEmitter*, PollInfo> EventPollMap_t; |
| 922 |
| 974 int KernelProxy::poll(struct pollfd *fds, nfds_t nfds, int timeout) { | 923 int KernelProxy::poll(struct pollfd *fds, nfds_t nfds, int timeout) { |
| 975 ScopedEventListener listener(new EventListener); | 924 EventPollMap_t event_map; |
| 976 listener->Track(-1, signal_emitter_, POLLERR, 0); | |
| 977 | 925 |
| 978 int index; | 926 std::vector<EventRequest> requests; |
| 979 size_t event_cnt = 0; | 927 size_t event_cnt = 0; |
| 980 size_t event_track = 1; | 928 |
| 981 for (index = 0; static_cast<nfds_t>(index) < nfds; index++) { | 929 for (int index = 0; static_cast<nfds_t>(index) < nfds; index++) { |
| 982 ScopedKernelHandle handle; | 930 ScopedKernelHandle handle; |
| 983 struct pollfd* info = &fds[index]; | 931 struct pollfd* fd_info = &fds[index]; |
| 984 Error err = AcquireHandle(info->fd, &handle); | 932 Error err = AcquireHandle(fd_info->fd, &handle); |
| 933 |
| 934 fd_info->revents = 0; |
| 985 | 935 |
| 986 // If the node isn't open, or somehow invalid, mark it so. | 936 // If the node isn't open, or somehow invalid, mark it so. |
| 987 if (err != 0) { | 937 if (err != 0) { |
| 988 info->revents = POLLNVAL; | 938 fd_info->revents = POLLNVAL; |
| 989 event_cnt++; | 939 event_cnt++; |
| 990 continue; | 940 continue; |
| 991 } | 941 } |
| 992 | 942 |
| 993 // If it's already signaled, then just capture the event | 943 // If it's already signaled, then just capture the event |
| 994 if (handle->node()->GetEventStatus() & info->events) { | 944 ScopedEventEmitter emitter(handle->node()->GetEventEmitter()); |
| 995 info->revents = info->events & handle->node()->GetEventStatus(); | 945 int events = POLLIN | POLLOUT; |
| 946 if (emitter) |
| 947 events = emitter->GetEventStatus(); |
| 948 |
| 949 if (events & fd_info->events) { |
| 950 fd_info->revents = events & fd_info->events; |
| 951 event_cnt++; |
| 952 continue; |
| 953 } |
| 954 |
| 955 if (NULL == emitter) { |
| 956 fd_info->revents = POLLNVAL; |
| 996 event_cnt++; | 957 event_cnt++; |
| 997 continue; | 958 continue; |
| 998 } | 959 } |
| 999 | 960 |
| 1000 // Otherwise try to track it. | 961 // Otherwise try to track it. |
| 1001 err = listener->Track(info->fd, handle->node(), info->events, index); | 962 PollInfo* info = &event_map[emitter.get()]; |
| 1002 if (err != 0) { | 963 if (info->index == -1) { |
| 1003 info->revents = POLLNVAL; | 964 EventRequest request; |
| 1004 event_cnt++; | 965 request.emitter = emitter; |
| 1005 continue; | 966 request.filter = fd_info->events; |
| 967 request.events = 0; |
| 968 |
| 969 info->index = requests.size(); |
| 970 requests.push_back(request); |
| 1006 } | 971 } |
| 1007 event_track++; | 972 info->fds.push_back(fd_info); |
| 973 requests[info->index].filter |= fd_info->events; |
| 1008 } | 974 } |
| 1009 | 975 |
| 1010 // If nothing is signaled, then we must wait. | 976 // If nothing is signaled, then we must wait on the event map |
| 1011 if (0 == event_cnt) { | 977 if (0 == event_cnt) { |
| 1012 std::vector<EventData> events; | 978 EventListenerPoll wait; |
| 1013 int ready_cnt; | 979 Error err = wait.WaitOnAny(&requests[0], requests.size(), timeout); |
| 980 if ((err != 0) && (err != ETIMEDOUT)) { |
| 981 errno = err; |
| 982 return -1; |
| 983 } |
| 1014 | 984 |
| 1015 bool interrupted = false; | 985 for (size_t rindex = 0; rindex < requests.size(); rindex++) { |
| 1016 events.resize(event_track); | 986 EventRequest* request = &requests[rindex]; |
| 1017 listener->Wait(events.data(), event_track, timeout, &ready_cnt); | 987 if (request->events) { |
| 1018 for (index = 0; index < ready_cnt; index++) { | 988 PollInfo* poll_info = &event_map[request->emitter.get()]; |
| 1019 struct pollfd* info = &fds[events[index].user_data]; | 989 for (size_t findex = 0; findex < poll_info->fds.size(); findex++) { |
| 1020 if (!info) { | 990 struct pollfd* fd_info = poll_info->fds[findex]; |
| 1021 interrupted = true; | 991 uint32_t events = fd_info->events & request->events; |
| 1022 continue; | 992 if (events) { |
| 993 fd_info->revents = events; |
| 994 event_cnt++; |
| 995 } |
| 996 } |
| 1023 } | 997 } |
| 1024 | |
| 1025 info->revents = events[index].events; | |
| 1026 event_cnt++; | |
| 1027 } | |
| 1028 if (0 == event_cnt && interrupted) { | |
| 1029 errno = EINTR; | |
| 1030 return -1; | |
| 1031 } | 998 } |
| 1032 } | 999 } |
| 1033 | 1000 |
| 1034 return event_cnt; | 1001 return event_cnt; |
| 1035 } | 1002 } |
| 1036 | 1003 |
| 1037 | 1004 |
| 1038 | 1005 |
| 1039 // Socket Functions | 1006 // Socket Functions |
| 1040 int KernelProxy::accept(int fd, struct sockaddr* addr, socklen_t* len) { | 1007 int KernelProxy::accept(int fd, struct sockaddr* addr, socklen_t* len) { |
| (...skipping 289 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1330 | 1297 |
| 1331 int KernelProxy::socket(int domain, int type, int protocol) { | 1298 int KernelProxy::socket(int domain, int type, int protocol) { |
| 1332 if (AF_INET != domain && AF_INET6 != domain) { | 1299 if (AF_INET != domain && AF_INET6 != domain) { |
| 1333 errno = EAFNOSUPPORT; | 1300 errno = EAFNOSUPPORT; |
| 1334 return -1; | 1301 return -1; |
| 1335 } | 1302 } |
| 1336 | 1303 |
| 1337 MountNodeSocket* sock = NULL; | 1304 MountNodeSocket* sock = NULL; |
| 1338 switch (type) { | 1305 switch (type) { |
| 1339 case SOCK_DGRAM: | 1306 case SOCK_DGRAM: |
| 1340 sock = new MountNodeUDP(socket_mount_.get()); | 1307 sock = new MountNodeUDP(stream_mount_.get()); |
| 1341 break; | 1308 break; |
| 1342 | 1309 |
| 1343 case SOCK_STREAM: | 1310 case SOCK_STREAM: |
| 1344 sock = new MountNodeTCP(socket_mount_.get()); | 1311 sock = new MountNodeTCP(stream_mount_.get()); |
| 1345 break; | 1312 break; |
| 1346 | 1313 |
| 1347 default: | 1314 default: |
| 1348 errno = EPROTONOSUPPORT; | 1315 errno = EPROTONOSUPPORT; |
| 1349 return -1; | 1316 return -1; |
| 1350 } | 1317 } |
| 1351 | 1318 |
| 1352 ScopedMountNode node(sock); | 1319 ScopedMountNode node(sock); |
| 1353 if (sock->Init(S_IREAD | S_IWRITE) == 0) { | 1320 if (sock->Init(S_IREAD | S_IWRITE) == 0) { |
| 1354 ScopedKernelHandle handle(new KernelHandle(socket_mount_, node)); | 1321 ScopedKernelHandle handle(new KernelHandle(stream_mount_, node)); |
| 1355 return AllocateFD(handle); | 1322 return AllocateFD(handle); |
| 1356 } | 1323 } |
| 1357 | 1324 |
| 1358 // If we failed to init, assume we don't have access. | 1325 // If we failed to init, assume we don't have access. |
| 1359 return EACCES; | 1326 return EACCES; |
| 1360 } | 1327 } |
| 1361 | 1328 |
| 1362 int KernelProxy::socketpair(int domain, int type, int protocol, int* sv) { | 1329 int KernelProxy::socketpair(int domain, int type, int protocol, int* sv) { |
| 1363 if (NULL == sv) { | 1330 if (NULL == sv) { |
| 1364 errno = EFAULT; | 1331 errno = EFAULT; |
| (...skipping 29 matching lines...) Expand all Loading... |
| 1394 errno = ENOTSOCK; | 1361 errno = ENOTSOCK; |
| 1395 return -1; | 1362 return -1; |
| 1396 } | 1363 } |
| 1397 | 1364 |
| 1398 return 0; | 1365 return 0; |
| 1399 } | 1366 } |
| 1400 | 1367 |
| 1401 #endif // PROVIDES_SOCKET_API | 1368 #endif // PROVIDES_SOCKET_API |
| 1402 | 1369 |
| 1403 } // namespace_nacl_io | 1370 } // namespace_nacl_io |
| OLD | NEW |