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