Chromium Code Reviews| 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 EventEmitterSignal) { |
| 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 handle0->Init(S_IREAD); | |
|
binji
2013/09/12 01:47:57
check return from Init?
noelallen1
2013/09/12 23:19:03
Done.
| |
| 187 handle1->Init(S_IWRITE); | |
| 188 | |
| 189 pipefds[0] = AllocateFD(handle0); | |
| 190 if (pipefds[0] == 0) | |
|
binji
2013/09/12 01:47:57
AllocateFD can never return a zero FD.
noelallen1
2013/09/12 23:19:03
Done.
| |
| 191 return -1; | |
| 192 | |
| 193 pipefds[1] = AllocateFD(handle1); | |
| 194 if (pipefds[1] == 0) { | |
| 195 close(pipefds[0]); | |
| 196 return -1; | |
| 197 } | |
| 198 | |
| 199 return 0; | |
| 200 } | |
| 201 | |
| 202 return -1; | |
|
binji
2013/09/12 01:47:57
set errno?
noelallen1
2013/09/12 23:19:03
Done.
| |
| 203 } | |
| 204 | |
| 196 int KernelProxy::close(int fd) { | 205 int KernelProxy::close(int fd) { |
| 197 ScopedKernelHandle handle; | 206 ScopedKernelHandle handle; |
| 198 Error error = AcquireHandle(fd, &handle); | 207 Error error = AcquireHandle(fd, &handle); |
| 199 if (error) { | 208 if (error) { |
| 200 errno = error; | 209 errno = error; |
| 201 return -1; | 210 return -1; |
| 202 } | 211 } |
| 203 | 212 |
| 204 // Remove the FD from the process open file descriptor map | 213 // Remove the FD from the process open file descriptor map |
| 205 FreeFD(fd); | 214 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 | 775 // Currently we don't even pretend that other processes exist |
| 767 // so we can only send a signal to outselves. For kill(2) | 776 // 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 | 777 // pid 0 means the current process group and -1 means all the |
| 769 // processes we have permission to send signals to. | 778 // processes we have permission to send signals to. |
| 770 if (pid != getpid() && pid != -1 && pid != 0) { | 779 if (pid != getpid() && pid != -1 && pid != 0) { |
| 771 errno = ESRCH; | 780 errno = ESRCH; |
| 772 return -1; | 781 return -1; |
| 773 } | 782 } |
| 774 | 783 |
| 775 // Raise an event so that select/poll get interrupted. | 784 // Raise an event so that select/poll get interrupted. |
| 776 signal_emitter_->SignalOccurred(); | 785 signal_emitter_->Raise(POLLERR); |
| 777 switch (sig) { | 786 switch (sig) { |
| 778 case SIGWINCH: | 787 case SIGWINCH: |
| 779 if (sigwinch_handler_ != SIG_IGN) | 788 if (sigwinch_handler_ != SIG_IGN) |
| 780 sigwinch_handler_(SIGWINCH); | 789 sigwinch_handler_(SIGWINCH); |
| 781 break; | 790 break; |
| 782 | 791 |
| 783 case SIGUSR1: | 792 case SIGUSR1: |
| 784 case SIGUSR2: | 793 case SIGUSR2: |
| 785 break; | 794 break; |
| 786 | 795 |
| 787 default: | 796 default: |
| 788 errno = EINVAL; | 797 errno = EINVAL; |
| 789 return -1; | 798 return -1; |
| 790 } | 799 } |
| 791 | |
| 792 return 0; | 800 return 0; |
| 793 } | 801 } |
| 794 | 802 |
| 795 sighandler_t KernelProxy::sigset(int signum, sighandler_t handler) { | 803 sighandler_t KernelProxy::sigset(int signum, sighandler_t handler) { |
| 796 switch (signum) { | 804 switch (signum) { |
| 797 // Handled signals. | 805 // Handled signals. |
| 798 case SIGWINCH: { | 806 case SIGWINCH: { |
| 799 sighandler_t old_value = sigwinch_handler_; | 807 sighandler_t old_value = sigwinch_handler_; |
| 800 if (handler == SIG_DFL) | 808 if (handler == SIG_DFL) |
| 801 handler = SIG_IGN; | 809 handler = SIG_IGN; |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 824 } | 832 } |
| 825 | 833 |
| 826 errno = EINVAL; | 834 errno = EINVAL; |
| 827 return SIG_ERR; | 835 return SIG_ERR; |
| 828 } | 836 } |
| 829 | 837 |
| 830 #ifdef PROVIDES_SOCKET_API | 838 #ifdef PROVIDES_SOCKET_API |
| 831 | 839 |
| 832 int KernelProxy::select(int nfds, fd_set* readfds, fd_set* writefds, | 840 int KernelProxy::select(int nfds, fd_set* readfds, fd_set* writefds, |
| 833 fd_set* exceptfds, struct timeval* timeout) { | 841 fd_set* exceptfds, struct timeval* timeout) { |
| 834 ScopedEventListener listener(new EventListener); | 842 std::vector<pollfd> pollfds; |
| 835 | 843 |
| 836 std::vector<struct pollfd> fds; | 844 for (int fd = 0; fd < nfds; fd++) { |
| 837 | |
| 838 fd_set readout, writeout, exceptout; | |
| 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; | 845 int events = 0; |
| 849 | |
| 850 if (readfds != NULL && FD_ISSET(fd, readfds)) | 846 if (readfds != NULL && FD_ISSET(fd, readfds)) |
| 851 events |= POLLIN; | 847 events |= POLLIN; |
| 852 | 848 |
| 853 if (writefds != NULL && FD_ISSET(fd, writefds)) | 849 if (writefds != NULL && FD_ISSET(fd, writefds)) |
| 854 events |= POLLOUT; | 850 events |= POLLOUT; |
| 855 | 851 |
| 856 if (exceptfds != NULL && FD_ISSET(fd, exceptfds)) | 852 if (exceptfds != NULL && FD_ISSET(fd, exceptfds)) |
| 857 events |= POLLERR | POLLHUP; | 853 events |= POLLERR | POLLHUP; |
| 858 | 854 |
| 859 // If we are not interested in this FD, skip it | 855 if (events) { |
| 860 if (0 == events) continue; | 856 pollfd info; |
| 857 info.fd = fd; | |
| 858 info.events = events; | |
| 859 pollfds.push_back(info); | |
| 860 } | |
| 861 } | |
| 861 | 862 |
| 862 ScopedKernelHandle handle; | 863 // NULL timeout signals wait forever. |
| 863 Error err = AcquireHandle(fd, &handle); | 864 int ms_timeout = -1; |
| 865 if (timeout != NULL) { | |
| 866 int64_t ms = timeout->tv_sec * 1000 + ((timeout->tv_usec + 500) / 1000); | |
| 864 | 867 |
| 865 // Select will return immediately if there are bad FDs. | 868 // If the timeout is invalid or too long (larger than signed 32 bit). |
| 866 if (err != 0) { | 869 if ((timeout->tv_sec < 0) || (timeout->tv_sec >= (INT_MAX / 1000)) || |
| 867 errno = EBADF; | 870 (timeout->tv_usec < 0) || (timeout->tv_usec >= 1000000) || |
| 871 (ms < 0) || (ms >= INT_MAX)) { | |
| 872 errno = EINVAL; | |
| 868 return -1; | 873 return -1; |
| 869 } | 874 } |
| 870 | 875 |
| 871 int status = handle->node()->GetEventStatus() & events; | 876 ms_timeout = static_cast<int>(ms); |
| 872 if (status & POLLIN) { | 877 } |
| 873 FD_SET(fd, &readout); | 878 |
| 879 int result = poll(&pollfds[0], pollfds.size(), ms_timeout); | |
| 880 if (result == -1) | |
| 881 return -1; | |
| 882 | |
| 883 FD_ZERO(readfds); | |
| 884 FD_ZERO(writefds); | |
| 885 FD_ZERO(exceptfds); | |
| 886 | |
| 887 int event_cnt = 0; | |
| 888 for (size_t index = 0; index < pollfds.size(); index++) { | |
| 889 pollfd* info = &pollfds[index]; | |
| 890 if (info->revents & POLLIN) { | |
| 891 FD_SET(info->fd, readfds); | |
| 874 event_cnt++; | 892 event_cnt++; |
| 875 } | 893 } |
| 876 | 894 if (info->revents & POLLOUT) { |
| 877 if (status & POLLOUT) { | 895 FD_SET(info->fd, writefds); |
| 878 FD_SET(fd, &writeout); | |
| 879 event_cnt++; | 896 event_cnt++; |
| 880 } | 897 } |
| 881 | 898 if (info->revents & POLLHUP) { |
|
binji
2013/09/12 01:47:57
not POLLERR? You request it above.
noelallen1
2013/09/12 23:19:03
Done.
| |
| 882 if (status & (POLLERR | POLLHUP)) { | 899 FD_SET(info->fd, exceptfds); |
| 883 FD_SET(fd, &exceptout); | |
| 884 event_cnt++; | 900 event_cnt++; |
| 885 } | 901 } |
| 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 } | 902 } |
| 897 | 903 |
| 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; | 904 return event_cnt; |
| 972 } | 905 } |
| 973 | 906 |
| 907 struct PollInfo { | |
| 908 PollInfo() : index(-1) {}; | |
| 909 | |
| 910 std::vector<struct pollfd*> fds; | |
| 911 int index; | |
| 912 }; | |
| 913 | |
| 914 typedef std::map<EventEmitter*, PollInfo> EventPollMap_t; | |
| 915 | |
| 974 int KernelProxy::poll(struct pollfd *fds, nfds_t nfds, int timeout) { | 916 int KernelProxy::poll(struct pollfd *fds, nfds_t nfds, int timeout) { |
| 975 ScopedEventListener listener(new EventListener); | 917 EventPollMap_t event_map; |
| 976 listener->Track(-1, signal_emitter_, POLLERR, 0); | |
| 977 | 918 |
| 978 int index; | 919 std::vector<EventRequest> requests; |
| 979 size_t event_cnt = 0; | 920 size_t event_cnt = 0; |
| 980 size_t event_track = 1; | 921 |
| 981 for (index = 0; static_cast<nfds_t>(index) < nfds; index++) { | 922 for (int index = 0; static_cast<nfds_t>(index) < nfds; index++) { |
| 982 ScopedKernelHandle handle; | 923 ScopedKernelHandle handle; |
| 983 struct pollfd* info = &fds[index]; | 924 struct pollfd* fd_info = &fds[index]; |
| 984 Error err = AcquireHandle(info->fd, &handle); | 925 Error err = AcquireHandle(fd_info->fd, &handle); |
| 985 | 926 |
| 986 // If the node isn't open, or somehow invalid, mark it so. | 927 // If the node isn't open, or somehow invalid, mark it so. |
| 987 if (err != 0) { | 928 if (err != 0) { |
| 988 info->revents = POLLNVAL; | 929 fd_info->revents = POLLNVAL; |
| 989 event_cnt++; | 930 event_cnt++; |
| 990 continue; | 931 continue; |
| 991 } | 932 } |
| 992 | 933 |
| 993 // If it's already signaled, then just capture the event | 934 // If it's already signaled, then just capture the event |
| 994 if (handle->node()->GetEventStatus() & info->events) { | 935 ScopedEventEmitter emitter(handle->node()->GetEventEmitter()); |
| 995 info->revents = info->events & handle->node()->GetEventStatus(); | 936 int events = POLLIN | POLLOUT; |
| 937 if (emitter) | |
| 938 events = emitter->GetEventStatus(); | |
| 939 | |
| 940 if (events & fd_info->events) { | |
| 941 fd_info->revents = fd_info->events & events; | |
|
binji
2013/09/12 01:47:57
change to "events & fd_info->events" like above?
noelallen1
2013/09/12 23:19:03
Done.
| |
| 942 event_cnt++; | |
| 943 continue; | |
| 944 } | |
| 945 | |
| 946 if (NULL == emitter) { | |
| 947 fd_info->revents = POLLNVAL; | |
| 996 event_cnt++; | 948 event_cnt++; |
| 997 continue; | 949 continue; |
| 998 } | 950 } |
| 999 | 951 |
| 1000 // Otherwise try to track it. | 952 // Otherwise try to track it. |
| 1001 err = listener->Track(info->fd, handle->node(), info->events, index); | 953 PollInfo* info = &event_map[emitter.get()]; |
|
binji
2013/09/12 01:47:57
this is a lot of extra work to prevent sending the
noelallen1
2013/09/12 23:19:03
Having a one-to-one mapping between Listener and E
| |
| 1002 if (err != 0) { | 954 if (info->index == -1) { |
| 1003 info->revents = POLLNVAL; | 955 EventRequest request; |
| 1004 event_cnt++; | 956 request.emitter = emitter; |
| 1005 continue; | 957 request.filter = fd_info->events; |
| 958 request.events = 0; | |
| 959 | |
| 960 info->index = requests.size(); | |
| 961 requests.push_back(request); | |
| 1006 } | 962 } |
| 1007 event_track++; | 963 info->fds.push_back(fd_info); |
| 964 requests[info->index].filter |= fd_info->events; | |
| 1008 } | 965 } |
| 1009 | 966 |
| 1010 // If nothing is signaled, then we must wait. | 967 // If nothing is signaled, then we must wait on the event map |
| 1011 if (0 == event_cnt) { | 968 if (0 == event_cnt) { |
| 1012 std::vector<EventData> events; | 969 EventListenerPoll wait; |
| 1013 int ready_cnt; | 970 Error err = wait.WaitOnAny(&requests[0], requests.size(), timeout); |
| 971 if (err != 0) { | |
| 972 errno = err; | |
| 973 return -1; | |
| 974 } | |
| 1014 | 975 |
| 1015 bool interrupted = false; | 976 for (size_t rindex = 0; rindex < requests.size(); rindex++) { |
| 1016 events.resize(event_track); | 977 EventRequest* request = &requests[rindex]; |
| 1017 listener->Wait(events.data(), event_track, timeout, &ready_cnt); | 978 if (request->events) { |
| 1018 for (index = 0; index < ready_cnt; index++) { | 979 PollInfo* poll_info = &event_map[request->emitter.get()]; |
| 1019 struct pollfd* info = &fds[events[index].user_data]; | 980 for (size_t findex = 0; findex < poll_info->fds.size(); findex++) { |
| 1020 if (!info) { | 981 struct pollfd* fd_info = poll_info->fds[findex]; |
| 1021 interrupted = true; | 982 uint32_t events = fd_info->events & request->events; |
| 1022 continue; | 983 if (events) { |
| 984 fd_info->revents = events; | |
| 985 event_cnt++; | |
| 986 } | |
| 987 } | |
| 1023 } | 988 } |
| 1024 | |
| 1025 info->revents = events[index].events; | |
| 1026 event_cnt++; | |
| 1027 } | |
| 1028 if (0 == event_cnt && interrupted) { | |
| 1029 errno = EINTR; | |
| 1030 return -1; | |
| 1031 } | 989 } |
| 1032 } | 990 } |
| 1033 | 991 |
| 1034 return event_cnt; | 992 return event_cnt; |
| 1035 } | 993 } |
| 1036 | 994 |
| 1037 | 995 |
| 1038 | 996 |
| 1039 // Socket Functions | 997 // Socket Functions |
| 1040 int KernelProxy::accept(int fd, struct sockaddr* addr, socklen_t* len) { | 998 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 | 1288 |
| 1331 int KernelProxy::socket(int domain, int type, int protocol) { | 1289 int KernelProxy::socket(int domain, int type, int protocol) { |
| 1332 if (AF_INET != domain && AF_INET6 != domain) { | 1290 if (AF_INET != domain && AF_INET6 != domain) { |
| 1333 errno = EAFNOSUPPORT; | 1291 errno = EAFNOSUPPORT; |
| 1334 return -1; | 1292 return -1; |
| 1335 } | 1293 } |
| 1336 | 1294 |
| 1337 MountNodeSocket* sock = NULL; | 1295 MountNodeSocket* sock = NULL; |
| 1338 switch (type) { | 1296 switch (type) { |
| 1339 case SOCK_DGRAM: | 1297 case SOCK_DGRAM: |
| 1340 sock = new MountNodeUDP(socket_mount_.get()); | 1298 sock = new MountNodeUDP(stream_mount_.get()); |
| 1341 break; | 1299 break; |
| 1342 | 1300 |
| 1343 case SOCK_STREAM: | 1301 case SOCK_STREAM: |
| 1344 sock = new MountNodeTCP(socket_mount_.get()); | 1302 sock = new MountNodeTCP(stream_mount_.get()); |
| 1345 break; | 1303 break; |
| 1346 | 1304 |
| 1347 default: | 1305 default: |
| 1348 errno = EPROTONOSUPPORT; | 1306 errno = EPROTONOSUPPORT; |
| 1349 return -1; | 1307 return -1; |
| 1350 } | 1308 } |
| 1351 | 1309 |
| 1352 ScopedMountNode node(sock); | 1310 ScopedMountNode node(sock); |
| 1353 if (sock->Init(S_IREAD | S_IWRITE) == 0) { | 1311 if (sock->Init(S_IREAD | S_IWRITE) == 0) { |
| 1354 ScopedKernelHandle handle(new KernelHandle(socket_mount_, node)); | 1312 ScopedKernelHandle handle(new KernelHandle(stream_mount_, node)); |
| 1355 return AllocateFD(handle); | 1313 return AllocateFD(handle); |
| 1356 } | 1314 } |
| 1357 | 1315 |
| 1358 // If we failed to init, assume we don't have access. | 1316 // If we failed to init, assume we don't have access. |
| 1359 return EACCES; | 1317 return EACCES; |
| 1360 } | 1318 } |
| 1361 | 1319 |
| 1362 int KernelProxy::socketpair(int domain, int type, int protocol, int* sv) { | 1320 int KernelProxy::socketpair(int domain, int type, int protocol, int* sv) { |
| 1363 if (NULL == sv) { | 1321 if (NULL == sv) { |
| 1364 errno = EFAULT; | 1322 errno = EFAULT; |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 1394 errno = ENOTSOCK; | 1352 errno = ENOTSOCK; |
| 1395 return -1; | 1353 return -1; |
| 1396 } | 1354 } |
| 1397 | 1355 |
| 1398 return 0; | 1356 return 0; |
| 1399 } | 1357 } |
| 1400 | 1358 |
| 1401 #endif // PROVIDES_SOCKET_API | 1359 #endif // PROVIDES_SOCKET_API |
| 1402 | 1360 |
| 1403 } // namespace_nacl_io | 1361 } // namespace_nacl_io |
| OLD | NEW |