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