Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(76)

Side by Side Diff: native_client_sdk/src/libraries/nacl_io/kernel_proxy.cc

Issue 23498015: [NaCl SDK] Support non blocking TCP/UDP (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Merge Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « native_client_sdk/src/libraries/nacl_io/kernel_proxy.h ('k') | native_client_sdk/src/libraries/nacl_io/library.dsc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698