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