kernel_proxy.cc revision 3551c9c881056c480085172ff9840cab31610854
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
3// found in the LICENSE file.
4
5#include "nacl_io/kernel_proxy.h"
6
7
8#include <assert.h>
9#include <errno.h>
10#include <fcntl.h>
11#include <limits.h>
12#include <poll.h>
13#include <pthread.h>
14#include <stdio.h>
15#include <string.h>
16#include <sys/time.h>
17#include <unistd.h>
18
19#include <iterator>
20#include <string>
21
22#include "nacl_io/dbgprint.h"
23#include "nacl_io/host_resolver.h"
24#include "nacl_io/kernel_handle.h"
25#include "nacl_io/kernel_wrap_real.h"
26#include "nacl_io/mount.h"
27#include "nacl_io/mount_dev.h"
28#include "nacl_io/mount_html5fs.h"
29#include "nacl_io/mount_http.h"
30#include "nacl_io/mount_mem.h"
31#include "nacl_io/mount_node.h"
32#include "nacl_io/mount_node_tcp.h"
33#include "nacl_io/mount_node_udp.h"
34#include "nacl_io/mount_passthrough.h"
35#include "nacl_io/osmman.h"
36#include "nacl_io/ossocket.h"
37#include "nacl_io/osstat.h"
38#include "nacl_io/path.h"
39#include "nacl_io/pepper_interface.h"
40#include "nacl_io/typed_mount_factory.h"
41#include "sdk_util/auto_lock.h"
42#include "sdk_util/ref_object.h"
43
44#ifndef MAXPATHLEN
45#define MAXPATHLEN 256
46#endif
47
48namespace nacl_io {
49
50class SignalEmitter : public EventEmitter {
51 public:
52  // From EventEmitter.  The SignalEmitter exists in order
53  // to inturrupt anything waiting in select()/poll() when kill()
54  // is called.  It is an edge trigger only and therefore has no
55  // persistent readable/wriable/error state.
56  uint32_t GetEventStatus() {
57     return 0;
58  }
59
60  int GetType() {
61    // For lack of a better type, report socket to signify it can be in an
62    // used to signal.
63    return S_IFSOCK;
64  }
65
66  void SignalOccurred() {
67    RaiseEvent(POLLERR);
68  }
69};
70
71KernelProxy::KernelProxy() : dev_(0), ppapi_(NULL),
72                             sigwinch_handler_(SIG_IGN),
73                             signal_emitter_(new SignalEmitter) {
74
75}
76
77KernelProxy::~KernelProxy() {
78  // Clean up the MountFactories.
79  for (MountFactoryMap_t::iterator i = factories_.begin();
80       i != factories_.end();
81       ++i) {
82    delete i->second;
83  }
84
85  delete ppapi_;
86}
87
88void KernelProxy::Init(PepperInterface* ppapi) {
89  ppapi_ = ppapi;
90  dev_ = 1;
91
92  factories_["memfs"] = new TypedMountFactory<MountMem>;
93  factories_["dev"] = new TypedMountFactory<MountDev>;
94  factories_["html5fs"] = new TypedMountFactory<MountHtml5Fs>;
95  factories_["httpfs"] = new TypedMountFactory<MountHttp>;
96  factories_["passthroughfs"] = new TypedMountFactory<MountPassthrough>;
97
98  int result;
99  result = mount("", "/", "passthroughfs", 0, NULL);
100  assert(result == 0);
101
102  result = mount("", "/dev", "dev", 0, NULL);
103  assert(result == 0);
104
105  // Open the first three in order to get STDIN, STDOUT, STDERR
106  open("/dev/stdin", O_RDONLY);
107  open("/dev/stdout", O_WRONLY);
108  open("/dev/stderr", O_WRONLY);
109
110#ifdef PROVIDES_SOCKET_API
111  host_resolver_.Init(ppapi_);
112#endif
113
114  StringMap_t args;
115  socket_mount_.reset(new MountSocket());
116  socket_mount_->Init(0, args, ppapi);
117}
118
119int KernelProxy::open_resource(const char* path) {
120  ScopedMount mnt;
121  Path rel;
122
123  Error error = AcquireMountAndRelPath(path, &mnt, &rel);
124  if (error) {
125    errno = error;
126    return -1;
127  }
128
129  ScopedMountNode node;
130  error = mnt->OpenResource(rel, &node);
131  if (error) {
132    // OpenResource failed, try Open().
133    error = mnt->Open(rel, O_RDONLY, &node);
134    if (error) {
135      errno = error;
136      return -1;
137    }
138  }
139
140  ScopedKernelHandle handle(new KernelHandle(mnt, node));
141  error = handle->Init(O_RDONLY);
142  if (error) {
143    errno = error;
144    return -1;
145  }
146
147  return AllocateFD(handle);
148}
149
150int KernelProxy::open(const char* path, int oflags) {
151  ScopedMount mnt;
152  ScopedMountNode node;
153
154  Error error = AcquireMountAndNode(path, oflags, &mnt, &node);
155  if (error) {
156    errno = error;
157    return -1;
158  }
159
160  ScopedKernelHandle handle(new KernelHandle(mnt, node));
161  error = handle->Init(oflags);
162  if (error) {
163    errno = error;
164    return -1;
165  }
166
167  return AllocateFD(handle);
168}
169
170int KernelProxy::close(int fd) {
171  ScopedKernelHandle handle;
172  Error error = AcquireHandle(fd, &handle);
173  if (error) {
174    errno = error;
175    return -1;
176  }
177
178  // Remove the FD from the process open file descriptor map
179  FreeFD(fd);
180  return 0;
181}
182
183int KernelProxy::dup(int oldfd) {
184  ScopedKernelHandle handle;
185  Error error = AcquireHandle(oldfd, &handle);
186  if (error) {
187    errno = error;
188    return -1;
189  }
190
191  return AllocateFD(handle);
192}
193
194int KernelProxy::dup2(int oldfd, int newfd) {
195  // If it's the same file handle, just return
196  if (oldfd == newfd)
197    return newfd;
198
199  ScopedKernelHandle old_handle;
200  Error error = AcquireHandle(oldfd, &old_handle);
201  if (error) {
202    errno = error;
203    return -1;
204  }
205
206  FreeAndReassignFD(newfd, old_handle);
207  return newfd;
208}
209
210int KernelProxy::chdir(const char* path) {
211  Error error = SetCWD(path);
212  if (error) {
213    errno = error;
214    return -1;
215  }
216  return 0;
217}
218
219char* KernelProxy::getcwd(char* buf, size_t size) {
220  std::string cwd = GetCWD();
221
222  if (size <= 0) {
223    errno = EINVAL;
224    return NULL;
225  }
226
227  // If size is 0, allocate as much as we need.
228  if (size == 0) {
229    size = cwd.size() + 1;
230  }
231
232  // Verify the buffer is large enough
233  if (size <= cwd.size()) {
234    errno = ERANGE;
235    return NULL;
236  }
237
238  // Allocate the buffer if needed
239  if (buf == NULL) {
240    buf = static_cast<char*>(malloc(size));
241  }
242
243  strcpy(buf, cwd.c_str());
244  return buf;
245}
246
247char* KernelProxy::getwd(char* buf) {
248  if (NULL == buf) {
249    errno = EFAULT;
250    return NULL;
251  }
252  return getcwd(buf, MAXPATHLEN);
253}
254
255int KernelProxy::chmod(const char* path, mode_t mode) {
256  int fd = KernelProxy::open(path, O_RDONLY);
257  if (-1 == fd)
258    return -1;
259
260  int result = fchmod(fd, mode);
261  close(fd);
262  return result;
263}
264
265int KernelProxy::chown(const char* path, uid_t owner, gid_t group) {
266  return 0;
267}
268
269int KernelProxy::fchown(int fd, uid_t owner, gid_t group) {
270  return 0;
271}
272
273int KernelProxy::lchown(const char* path, uid_t owner, gid_t group) {
274  return 0;
275}
276
277int KernelProxy::utime(const char* filename, const struct utimbuf* times) {
278  return 0;
279}
280
281int KernelProxy::mkdir(const char* path, mode_t mode) {
282  ScopedMount mnt;
283  Path rel;
284
285  Error error = AcquireMountAndRelPath(path, &mnt, &rel);
286  if (error) {
287    errno = error;
288    return -1;
289  }
290
291  error = mnt->Mkdir(rel, mode);
292  if (error) {
293    errno = error;
294    return -1;
295  }
296
297  return 0;
298}
299
300int KernelProxy::rmdir(const char* path) {
301  ScopedMount mnt;
302  Path rel;
303
304  Error error = AcquireMountAndRelPath(path, &mnt, &rel);
305  if (error) {
306    errno = error;
307    return -1;
308  }
309
310  error = mnt->Rmdir(rel);
311  if (error) {
312    errno = error;
313    return -1;
314  }
315
316  return 0;
317}
318
319int KernelProxy::stat(const char* path, struct stat* buf) {
320  int fd = open(path, O_RDONLY);
321  if (-1 == fd)
322    return -1;
323
324  int result = fstat(fd, buf);
325  close(fd);
326  return result;
327}
328
329
330int KernelProxy::mount(const char* source,
331                       const char* target,
332                       const char* filesystemtype,
333                       unsigned long mountflags,
334                       const void* data) {
335  std::string abs_path = GetAbsParts(target).Join();
336
337  // Find a factory of that type
338  MountFactoryMap_t::iterator factory = factories_.find(filesystemtype);
339  if (factory == factories_.end()) {
340    errno = ENODEV;
341    return -1;
342  }
343
344  // Create a map of settings
345  StringMap_t smap;
346  smap["SOURCE"] = source;
347  smap["TARGET"] = abs_path;
348
349  if (data) {
350    char* str = strdup(static_cast<const char*>(data));
351    char* ptr = strtok(str, ",");
352    char* val;
353    while (ptr != NULL) {
354      val = strchr(ptr, '=');
355      if (val) {
356        *val = 0;
357        smap[ptr] = val + 1;
358      } else {
359        smap[ptr] = "TRUE";
360      }
361      ptr = strtok(NULL, ",");
362    }
363    free(str);
364  }
365
366  ScopedMount mnt;
367  Error error = factory->second->CreateMount(dev_++, smap, ppapi_, &mnt);
368  if (error) {
369    errno = error;
370    return -1;
371  }
372
373  error = AttachMountAtPath(mnt, abs_path);
374  if (error) {
375    errno = error;
376    return -1;
377  }
378
379  return 0;
380}
381
382int KernelProxy::umount(const char* path) {
383  Error error = DetachMountAtPath(path);
384  if (error) {
385    errno = error;
386    return -1;
387  }
388  return 0;
389}
390
391ssize_t KernelProxy::read(int fd, void* buf, size_t nbytes) {
392  ScopedKernelHandle handle;
393  Error error = AcquireHandle(fd, &handle);
394  if (error) {
395    errno = error;
396    return -1;
397  }
398
399  int cnt = 0;
400  error = handle->Read(buf, nbytes, &cnt);
401  if (error) {
402    errno = error;
403    return -1;
404  }
405
406  return cnt;
407}
408
409ssize_t KernelProxy::write(int fd, const void* buf, size_t nbytes) {
410  ScopedKernelHandle handle;
411  Error error = AcquireHandle(fd, &handle);
412  if (error) {
413    errno = error;
414    return -1;
415  }
416
417  int cnt = 0;
418  error = handle->Write(buf, nbytes, &cnt);
419  if (error) {
420    errno = error;
421    return -1;
422  }
423
424  return cnt;
425}
426
427int KernelProxy::fstat(int fd, struct stat* buf) {
428  ScopedKernelHandle handle;
429  Error error = AcquireHandle(fd, &handle);
430  if (error) {
431    errno = error;
432    return -1;
433  }
434
435  error = handle->node()->GetStat(buf);
436  if (error) {
437    errno = error;
438    return -1;
439  }
440
441  return 0;
442}
443
444int KernelProxy::getdents(int fd, void* buf, unsigned int count) {
445  ScopedKernelHandle handle;
446  Error error = AcquireHandle(fd, &handle);
447  if (error) {
448    errno = error;
449    return -1;
450  }
451
452  int cnt = 0;
453  error = handle->GetDents(static_cast<dirent*>(buf), count, &cnt);
454  if (error)
455    errno = error;
456
457  return cnt;
458}
459
460int KernelProxy::ftruncate(int fd, off_t length) {
461  ScopedKernelHandle handle;
462  Error error = AcquireHandle(fd, &handle);
463  if (error) {
464    errno = error;
465    return -1;
466  }
467
468  error = handle->node()->FTruncate(length);
469  if (error) {
470    errno = error;
471    return -1;
472  }
473
474  return 0;
475}
476
477int KernelProxy::fsync(int fd) {
478  ScopedKernelHandle handle;
479  Error error = AcquireHandle(fd, &handle);
480  if (error) {
481    errno = error;
482    return -1;
483  }
484
485  error = handle->node()->FSync();
486  if (error) {
487    errno = error;
488    return -1;
489  }
490
491  return 0;
492}
493
494int KernelProxy::isatty(int fd) {
495  ScopedKernelHandle handle;
496  Error error = AcquireHandle(fd, &handle);
497  if (error) {
498    errno = error;
499    return -1;
500  }
501
502  error = handle->node()->IsaTTY();
503  if (error) {
504    errno = error;
505    return -1;
506  }
507
508  return 0;
509}
510
511int KernelProxy::ioctl(int fd, int request, char* argp) {
512  ScopedKernelHandle handle;
513  Error error = AcquireHandle(fd, &handle);
514  if (error) {
515    errno = error;
516    return -1;
517  }
518
519  error = handle->node()->Ioctl(request, argp);
520  if (error) {
521    errno = error;
522    return -1;
523  }
524
525  return 0;
526}
527
528off_t KernelProxy::lseek(int fd, off_t offset, int whence) {
529  ScopedKernelHandle handle;
530  Error error = AcquireHandle(fd, &handle);
531  if (error) {
532    errno = error;
533    return -1;
534  }
535
536  off_t new_offset;
537  error = handle->Seek(offset, whence, &new_offset);
538  if (error) {
539    errno = error;
540    return -1;
541  }
542
543  return new_offset;
544}
545
546int KernelProxy::unlink(const char* path) {
547  ScopedMount mnt;
548  Path rel;
549
550  Error error = AcquireMountAndRelPath(path, &mnt, &rel);
551  if (error) {
552    errno = error;
553    return -1;
554  }
555
556  error = mnt->Unlink(rel);
557  if (error) {
558    errno = error;
559    return -1;
560  }
561
562  return 0;
563}
564
565int KernelProxy::remove(const char* path) {
566  ScopedMount mnt;
567  Path rel;
568
569  Error error = AcquireMountAndRelPath(path, &mnt, &rel);
570  if (error) {
571    errno = error;
572    return -1;
573  }
574
575  error = mnt->Remove(rel);
576  if (error) {
577    errno = error;
578    return -1;
579  }
580
581  return 0;
582}
583
584// TODO(noelallen): Needs implementation.
585int KernelProxy::fchmod(int fd, int mode) {
586  ScopedKernelHandle handle;
587  Error error = AcquireHandle(fd, &handle);
588  if (error) {
589    errno = error;
590    return -1;
591  }
592
593  return 0;
594}
595
596int KernelProxy::access(const char* path, int amode) {
597  ScopedMount mnt;
598  Path rel;
599
600  Error error = AcquireMountAndRelPath(path, &mnt, &rel);
601  if (error) {
602    errno = error;
603    return -1;
604  }
605
606  error = mnt->Access(rel, amode);
607  if (error) {
608    errno = error;
609    return -1;
610  }
611  return 0;
612}
613
614// TODO(noelallen): Needs implementation.
615int KernelProxy::link(const char* oldpath, const char* newpath) {
616  errno = EINVAL;
617  return -1;
618}
619
620int KernelProxy::symlink(const char* oldpath, const char* newpath) {
621  errno = EINVAL;
622  return -1;
623}
624
625void* KernelProxy::mmap(void* addr,
626                        size_t length,
627                        int prot,
628                        int flags,
629                        int fd,
630                        size_t offset) {
631  // We shouldn't be getting anonymous mmaps here.
632  assert((flags & MAP_ANONYMOUS) == 0);
633  assert(fd != -1);
634
635  ScopedKernelHandle handle;
636  Error error = AcquireHandle(fd, &handle);
637  if (error) {
638    errno = error;
639    return MAP_FAILED;
640  }
641
642  void* new_addr;
643  error = handle->node()->MMap(addr, length, prot, flags, offset, &new_addr);
644  if (error) {
645    errno = error;
646    return MAP_FAILED;
647  }
648
649  return new_addr;
650}
651
652int KernelProxy::munmap(void* addr, size_t length) {
653  // NOTE: The comment below is from a previous discarded implementation that
654  // tracks mmap'd regions. For simplicity, we no longer do this; because we
655  // "snapshot" the contents of the file in mmap(), and don't support
656  // write-back or updating the mapped region when the file is written, holding
657  // on to the KernelHandle is pointless.
658  //
659  // If we ever do, these threading issues should be considered.
660
661  //
662  // WARNING: this function may be called by free().
663  //
664  // There is a potential deadlock scenario:
665  // Thread 1: open() -> takes lock1 -> free() -> takes lock2
666  // Thread 2: free() -> takes lock2 -> munmap() -> takes lock1
667  //
668  // Note that open() above could be any function that takes a lock that is
669  // shared with munmap (this includes munmap!)
670  //
671  // To prevent this, we avoid taking locks in munmap() that are used by other
672  // nacl_io functions that may call free. Specifically, we only take the
673  // mmap_lock, which is only shared with mmap() above. There is still a
674  // possibility of deadlock if mmap() or munmap() calls free(), so this is not
675  // allowed.
676  //
677  // Unfortunately, munmap still needs to acquire other locks; see the call to
678  // ReleaseHandle below which takes the process lock. This is safe as long as
679  // this is never executed from free() -- we can be reasonably sure this is
680  // true, because malloc only makes anonymous mmap() requests, and should only
681  // be munmapping those allocations. We never add to mmap_info_list_ for
682  // anonymous maps, so the unmap_list should always be empty when called from
683  // free().
684  return 0;
685}
686
687int KernelProxy::tcflush(int fd, int queue_selector) {
688  ScopedKernelHandle handle;
689  Error error = AcquireHandle(fd, &handle);
690  if (error) {
691    errno = error;
692    return -1;
693  }
694
695  error = handle->node()->Tcflush(queue_selector);
696  if (error) {
697    errno = error;
698    return -1;
699  }
700
701  return 0;
702}
703
704int KernelProxy::tcgetattr(int fd, struct termios* termios_p) {
705  ScopedKernelHandle handle;
706  Error error = AcquireHandle(fd, &handle);
707  if (error) {
708    errno = error;
709    return -1;
710  }
711
712  error = handle->node()->Tcgetattr(termios_p);
713  if (error) {
714    errno = error;
715    return -1;
716  }
717
718  return 0;
719}
720
721int KernelProxy::tcsetattr(int fd, int optional_actions,
722                           const struct termios *termios_p) {
723  ScopedKernelHandle handle;
724  Error error = AcquireHandle(fd, &handle);
725  if (error) {
726    errno = error;
727    return -1;
728  }
729
730  error = handle->node()->Tcsetattr(optional_actions, termios_p);
731  if (error) {
732    errno = error;
733    return -1;
734  }
735
736  return 0;
737}
738
739int KernelProxy::kill(pid_t pid, int sig) {
740  // Currently we don't even pretend that other processes exist
741  // so we can only send a signal to outselves.  For kill(2)
742  // pid 0 means the current process group and -1 means all the
743  // processes we have permission to send signals to.
744  if (pid != getpid() && pid != -1 && pid != 0) {
745    errno = ESRCH;
746    return -1;
747  }
748
749  // Raise an event so that select/poll get interrupted.
750  signal_emitter_->SignalOccurred();
751  switch (sig) {
752    case SIGWINCH:
753      if (sigwinch_handler_ != SIG_IGN)
754        sigwinch_handler_(SIGWINCH);
755      break;
756
757    case SIGUSR1:
758    case SIGUSR2:
759      break;
760
761    default:
762      errno = EINVAL;
763      return -1;
764  }
765
766  return 0;
767}
768
769sighandler_t KernelProxy::sigset(int signum, sighandler_t handler) {
770  switch (signum) {
771    // Handled signals.
772    case SIGWINCH: {
773      sighandler_t old_value = sigwinch_handler_;
774      if (handler == SIG_DFL)
775        handler = SIG_IGN;
776      sigwinch_handler_ = handler;
777      return old_value;
778    }
779
780    // Known signals
781    case SIGHUP:
782    case SIGINT:
783    case SIGKILL:
784    case SIGPIPE:
785    case SIGPOLL:
786    case SIGPROF:
787    case SIGTERM:
788    case SIGCHLD:
789    case SIGURG:
790    case SIGFPE:
791    case SIGILL:
792    case SIGQUIT:
793    case SIGSEGV:
794    case SIGTRAP:
795      if (handler == SIG_DFL)
796        return SIG_DFL;
797      break;
798  }
799
800  errno = EINVAL;
801  return SIG_ERR;
802}
803
804#ifdef PROVIDES_SOCKET_API
805
806int KernelProxy::select(int nfds, fd_set* readfds, fd_set* writefds,
807                        fd_set* exceptfds, struct timeval* timeout) {
808  ScopedEventListener listener(new EventListener);
809
810  std::vector<struct pollfd> fds;
811
812  fd_set readout, writeout, exceptout;
813
814  FD_ZERO(&readout);
815  FD_ZERO(&writeout);
816  FD_ZERO(&exceptout);
817
818  int fd;
819  size_t event_cnt = 0;
820  int event_track = 0;
821  for (fd = 0; fd < nfds; fd++) {
822    int events = 0;
823
824    if (readfds != NULL && FD_ISSET(fd, readfds))
825      events |= POLLIN;
826
827    if (writefds != NULL && FD_ISSET(fd, writefds))
828      events |= POLLOUT;
829
830    if (exceptfds != NULL && FD_ISSET(fd, exceptfds))
831      events |= POLLERR | POLLHUP;
832
833    // If we are not interested in this FD, skip it
834    if (0 == events) continue;
835
836    ScopedKernelHandle handle;
837    Error err = AcquireHandle(fd, &handle);
838
839    // Select will return immediately if there are bad FDs.
840    if (err != 0) {
841      errno = EBADF;
842      return -1;
843    }
844
845    int status = handle->node()->GetEventStatus() & events;
846    if (status & POLLIN) {
847      FD_SET(fd, &readout);
848      event_cnt++;
849    }
850
851    if (status & POLLOUT) {
852      FD_SET(fd, &writeout);
853      event_cnt++;
854    }
855
856    if (status & (POLLERR | POLLHUP)) {
857      FD_SET(fd, &exceptout);
858      event_cnt++;
859    }
860
861    // Otherwise track it.
862    if (0 == status) {
863      err = listener->Track(fd, handle->node(), events, fd);
864      if (err != 0) {
865        errno = EBADF;
866        return -1;
867      }
868      event_track++;
869    }
870  }
871
872  // If nothing is signaled, then we must wait.
873  if (event_cnt == 0) {
874    std::vector<EventData> events;
875    int ready_cnt;
876    int ms_timeout;
877
878    // NULL timeout signals wait forever.
879    if (timeout == NULL) {
880      ms_timeout = -1;
881    } else {
882      int64_t ms = timeout->tv_sec * 1000 + ((timeout->tv_usec + 500) / 1000);
883
884      // If the timeout is invalid or too long (larger than signed 32 bit).
885      if ((timeout->tv_sec < 0) || (timeout->tv_sec >= (INT_MAX / 1000)) ||
886          (timeout->tv_usec < 0) || (timeout->tv_usec >= 1000000) ||
887          (ms < 0) || (ms >= INT_MAX)) {
888        errno = EINVAL;
889        return -1;
890      }
891
892      ms_timeout = static_cast<int>(ms);
893    }
894
895    // Add a special node to listen for events
896    // coming from the KernelProxy itself (kill will
897    // generated a SIGERR event).
898    listener->Track(-1, signal_emitter_, POLLERR, -1);
899    event_track += 1;
900
901    events.resize(event_track);
902
903    bool interrupted = false;
904    listener->Wait(events.data(), event_track, ms_timeout, &ready_cnt);
905    for (fd = 0; static_cast<int>(fd) < ready_cnt; fd++) {
906      if (events[fd].user_data == static_cast<uint64_t>(-1)) {
907        if (events[fd].events & POLLERR) {
908          interrupted = true;
909        }
910        continue;
911      }
912
913      if (events[fd].events & POLLIN) {
914        FD_SET(events[fd].user_data, &readout);
915        event_cnt++;
916      }
917
918      if (events[fd].events & POLLOUT) {
919        FD_SET(events[fd].user_data, &writeout);
920        event_cnt++;
921      }
922
923      if (events[fd].events & (POLLERR | POLLHUP)) {
924        FD_SET(events[fd].user_data, &exceptout);
925        event_cnt++;
926      }
927    }
928
929    if (0 == event_cnt && interrupted) {
930      errno = EINTR;
931      return -1;
932    }
933  }
934
935  // Copy out the results
936  if (readfds != NULL)
937    *readfds = readout;
938
939  if (writefds != NULL)
940    *writefds = writeout;
941
942  if (exceptfds != NULL)
943    *exceptfds = exceptout;
944
945  return event_cnt;
946}
947
948int KernelProxy::poll(struct pollfd *fds, nfds_t nfds, int timeout) {
949  ScopedEventListener listener(new EventListener);
950  listener->Track(-1, signal_emitter_, POLLERR, 0);
951
952  int index;
953  size_t event_cnt = 0;
954  size_t event_track = 1;
955  for (index = 0; static_cast<nfds_t>(index) < nfds; index++) {
956    ScopedKernelHandle handle;
957    struct pollfd* info = &fds[index];
958    Error err = AcquireHandle(info->fd, &handle);
959
960    // If the node isn't open, or somehow invalid, mark it so.
961    if (err != 0) {
962      info->revents = POLLNVAL;
963      event_cnt++;
964      continue;
965    }
966
967    // If it's already signaled, then just capture the event
968    if (handle->node()->GetEventStatus() & info->events) {
969      info->revents = info->events & handle->node()->GetEventStatus();
970      event_cnt++;
971      continue;
972    }
973
974    // Otherwise try to track it.
975    err = listener->Track(info->fd, handle->node(), info->events, index);
976    if (err != 0) {
977      info->revents = POLLNVAL;
978      event_cnt++;
979      continue;
980    }
981    event_track++;
982  }
983
984  // If nothing is signaled, then we must wait.
985  if (0 == event_cnt) {
986    std::vector<EventData> events;
987    int ready_cnt;
988
989    bool interrupted = false;
990    events.resize(event_track);
991    listener->Wait(events.data(), event_track, timeout, &ready_cnt);
992    for (index = 0; index < ready_cnt; index++) {
993      struct pollfd* info = &fds[events[index].user_data];
994      if (!info) {
995        interrupted = true;
996        continue;
997      }
998
999      info->revents = events[index].events;
1000      event_cnt++;
1001    }
1002    if (0 == event_cnt && interrupted) {
1003      errno = EINTR;
1004      return -1;
1005    }
1006  }
1007
1008  return event_cnt;
1009}
1010
1011
1012
1013// Socket Functions
1014int KernelProxy::accept(int fd, struct sockaddr* addr, socklen_t* len) {
1015  if (NULL == addr || NULL == len) {
1016    errno = EFAULT;
1017    return -1;
1018  }
1019
1020  ScopedKernelHandle handle;
1021  if (AcquireSocketHandle(fd, &handle) == -1)
1022    return -1;
1023
1024  errno = EINVAL;
1025  return -1;
1026}
1027
1028int KernelProxy::bind(int fd, const struct sockaddr* addr, socklen_t len) {
1029  if (NULL == addr) {
1030    errno = EFAULT;
1031    return -1;
1032  }
1033
1034  ScopedKernelHandle handle;
1035  if (AcquireSocketHandle(fd, &handle) == -1)
1036    return -1;
1037
1038  Error err = handle->socket_node()->Bind(addr, len);
1039  if (err != 0) {
1040    errno = err;
1041    return -1;
1042  }
1043
1044  return 0;
1045}
1046
1047int KernelProxy::connect(int fd, const struct sockaddr* addr, socklen_t len) {
1048  if (NULL == addr) {
1049    errno = EFAULT;
1050    return -1;
1051  }
1052
1053  ScopedKernelHandle handle;
1054  if (AcquireSocketHandle(fd, &handle) == -1)
1055    return -1;
1056
1057  Error err = handle->socket_node()->Connect(addr, len);
1058  if (err != 0) {
1059    errno = err;
1060    return -1;
1061  }
1062
1063  return 0;
1064}
1065
1066struct hostent* KernelProxy::gethostbyname(const char* name) {
1067  return host_resolver_.gethostbyname(name);
1068}
1069
1070int KernelProxy::getpeername(int fd, struct sockaddr* addr, socklen_t* len) {
1071  if (NULL == addr || NULL == len) {
1072    errno = EFAULT;
1073    return -1;
1074  }
1075
1076  ScopedKernelHandle handle;
1077  if (AcquireSocketHandle(fd, &handle) == -1)
1078    return -1;
1079
1080  Error err = handle->socket_node()->GetPeerName(addr, len);
1081  if (err != 0) {
1082    errno = err;
1083    return -1;
1084  }
1085
1086  return 0;
1087}
1088
1089int KernelProxy::getsockname(int fd, struct sockaddr* addr, socklen_t* len) {
1090  if (NULL == addr || NULL == len) {
1091    errno = EFAULT;
1092    return -1;
1093  }
1094
1095  ScopedKernelHandle handle;
1096  if (AcquireSocketHandle(fd, &handle) == -1)
1097    return -1;
1098
1099  Error err = handle->socket_node()->GetSockName(addr, len);
1100  if (err != 0) {
1101    errno = err;
1102    return -1;
1103  }
1104
1105  return 0;
1106}
1107
1108int KernelProxy::getsockopt(int fd,
1109                         int lvl,
1110                         int optname,
1111                         void* optval,
1112                         socklen_t* len) {
1113  if (NULL == optval || NULL == len) {
1114    errno = EFAULT;
1115    return -1;
1116  }
1117
1118  ScopedKernelHandle handle;
1119  if (AcquireSocketHandle(fd, &handle) == -1)
1120    return -1;
1121
1122  errno = EINVAL;
1123  return -1;
1124}
1125
1126int KernelProxy::listen(int fd, int backlog) {
1127  ScopedKernelHandle handle;
1128  if (AcquireSocketHandle(fd, &handle) == -1)
1129    return -1;
1130
1131  errno = EOPNOTSUPP;
1132  return -1;
1133}
1134
1135ssize_t KernelProxy::recv(int fd,
1136                          void* buf,
1137                          size_t len,
1138                          int flags) {
1139  if (NULL == buf) {
1140    errno = EFAULT;
1141    return -1;
1142  }
1143
1144  ScopedKernelHandle handle;
1145  if (AcquireSocketHandle(fd, &handle) == -1)
1146    return -1;
1147
1148  int out_len = 0;
1149  Error err = handle->socket_node()->Recv(buf, len, flags, &out_len);
1150  if (err != 0) {
1151    errno = err;
1152    return -1;
1153  }
1154
1155  return static_cast<ssize_t>(out_len);
1156}
1157
1158ssize_t KernelProxy::recvfrom(int fd,
1159                              void* buf,
1160                              size_t len,
1161                              int flags,
1162                              struct sockaddr* addr,
1163                              socklen_t* addrlen) {
1164  // According to the manpage, recvfrom with a null addr is identical to recv.
1165  if (NULL == addr) {
1166    return recv(fd, buf, len, flags);
1167  }
1168
1169  if (NULL == buf || NULL == addrlen) {
1170    errno = EFAULT;
1171    return -1;
1172  }
1173
1174  ScopedKernelHandle handle;
1175  if (AcquireSocketHandle(fd, &handle) == -1)
1176    return -1;
1177
1178  int out_len = 0;
1179  Error err = handle->socket_node()->RecvFrom(buf,
1180                                              len,
1181                                              flags,
1182                                              addr,
1183                                              addrlen,
1184                                              &out_len);
1185  if (err != 0) {
1186    errno = err;
1187    return -1;
1188  }
1189
1190  return static_cast<ssize_t>(out_len);
1191}
1192
1193ssize_t KernelProxy::recvmsg(int fd, struct msghdr* msg, int flags) {
1194  if (NULL == msg ) {
1195    errno = EFAULT;
1196    return -1;
1197  }
1198
1199  ScopedKernelHandle handle;
1200  if (AcquireSocketHandle(fd, &handle) == -1)
1201    return -1;
1202
1203  errno = EOPNOTSUPP;
1204  return -1;
1205}
1206
1207ssize_t KernelProxy::send(int fd, const void* buf, size_t len, int flags) {
1208  if (NULL == buf) {
1209    errno = EFAULT;
1210    return -1;
1211  }
1212
1213  ScopedKernelHandle handle;
1214  if (AcquireSocketHandle(fd, &handle) == -1)
1215    return -1;
1216
1217  int out_len = 0;
1218  Error err = handle->socket_node()->Send(buf, len, flags, &out_len);
1219  if (err != 0) {
1220    errno = err;
1221    return -1;
1222  }
1223
1224  return static_cast<ssize_t>(out_len);
1225}
1226
1227ssize_t KernelProxy::sendto(int fd,
1228                            const void* buf,
1229                            size_t len,
1230                            int flags,
1231                            const struct sockaddr* addr,
1232                            socklen_t addrlen) {
1233  // According to the manpage, sendto with a null addr is identical to send.
1234  if (NULL == addr) {
1235    return send(fd, buf, len, flags);
1236  }
1237
1238  if (NULL == buf) {
1239    errno = EFAULT;
1240    return -1;
1241  }
1242
1243  ScopedKernelHandle handle;
1244  if (AcquireSocketHandle(fd, &handle) == -1)
1245    return -1;
1246
1247  int out_len = 0;
1248  Error err =
1249      handle->socket_node()->SendTo(buf, len, flags, addr, addrlen, &out_len);
1250
1251  if (err != 0) {
1252    errno = err;
1253    return -1;
1254  }
1255
1256  return static_cast<ssize_t>(out_len);
1257}
1258
1259ssize_t KernelProxy::sendmsg(int fd, const struct msghdr* msg, int flags) {
1260  if (NULL == msg) {
1261    errno = EFAULT;
1262    return -1;
1263  }
1264
1265  ScopedKernelHandle handle;
1266  if (AcquireSocketHandle(fd, &handle) == -1)
1267    return -1;
1268
1269  errno = EOPNOTSUPP;
1270  return -1;
1271}
1272
1273int KernelProxy::setsockopt(int fd,
1274                            int lvl,
1275                            int optname,
1276                            const void* optval,
1277                            socklen_t len) {
1278  if (NULL == optval) {
1279    errno = EFAULT;
1280    return -1;
1281  }
1282
1283  ScopedKernelHandle handle;
1284  if (AcquireSocketHandle(fd, &handle) == -1)
1285    return -1;
1286
1287  errno = EINVAL;
1288  return -1;
1289}
1290
1291int KernelProxy::shutdown(int fd, int how) {
1292  ScopedKernelHandle handle;
1293  if (AcquireSocketHandle(fd, &handle) == -1)
1294    return -1;
1295
1296  Error err = handle->socket_node()->Shutdown(how);
1297  if (err != 0) {
1298    errno = err;
1299    return -1;
1300  }
1301
1302  return 0;
1303}
1304
1305int KernelProxy::socket(int domain, int type, int protocol) {
1306  if (AF_INET != domain && AF_INET6 != domain) {
1307    errno = EAFNOSUPPORT;
1308    return -1;
1309  }
1310
1311  MountNodeSocket* sock = NULL;
1312  switch (type) {
1313    case SOCK_DGRAM:
1314      sock = new MountNodeUDP(socket_mount_.get());
1315      break;
1316
1317    case SOCK_STREAM:
1318      sock = new MountNodeTCP(socket_mount_.get());
1319      break;
1320
1321    default:
1322      errno = EPROTONOSUPPORT;
1323      return -1;
1324  }
1325
1326  ScopedMountNode node(sock);
1327  if (sock->Init(S_IREAD | S_IWRITE) == 0) {
1328    ScopedKernelHandle handle(new KernelHandle(socket_mount_, node));
1329    return AllocateFD(handle);
1330  }
1331
1332  // If we failed to init, assume we don't have access.
1333  return EACCES;
1334}
1335
1336int KernelProxy::socketpair(int domain, int type, int protocol, int* sv) {
1337  if (NULL == sv) {
1338    errno = EFAULT;
1339    return -1;
1340  }
1341
1342  // Catch-22: We don't support AF_UNIX, but any other AF doesn't support
1343  // socket pairs. Thus, this function always fails.
1344  if (AF_UNIX != domain) {
1345    errno = EPROTONOSUPPORT;
1346    return -1;
1347  }
1348
1349  if (AF_INET != domain && AF_INET6 != domain) {
1350    errno = EAFNOSUPPORT;
1351    return -1;
1352  }
1353
1354  // We cannot reach this point.
1355  errno = ENOSYS;
1356  return -1;
1357}
1358
1359int KernelProxy::AcquireSocketHandle(int fd, ScopedKernelHandle* handle) {
1360  Error error = AcquireHandle(fd, handle);
1361
1362  if (error) {
1363    errno = error;
1364    return -1;
1365  }
1366
1367  if ((handle->get()->node_->GetType() & S_IFSOCK) == 0) {
1368    errno = ENOTSOCK;
1369    return -1;
1370  }
1371
1372  return 0;
1373}
1374
1375#endif  // PROVIDES_SOCKET_API
1376
1377}  // namespace_nacl_io
1378