| 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 |