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