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