kernel_proxy.cc revision cedac228d2dd51db4b79ea1e72c7f249408ee061
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  smap["TARGET"] = abs_path;
428
429  if (data) {
430    std::vector<std::string> elements;
431    sdk_util::SplitString(static_cast<const char*>(data), ',', &elements);
432
433    for (std::vector<std::string>::const_iterator it = elements.begin();
434         it != elements.end();
435         ++it) {
436      size_t location = it->find('=');
437      if (location != std::string::npos) {
438        std::string key = it->substr(0, location);
439        std::string val = it->substr(location + 1);
440        smap[key] = val;
441      } else {
442        smap[*it] = "TRUE";
443      }
444    }
445  }
446
447  FsInitArgs args;
448  args.dev = dev_++;
449  args.string_map = smap;
450  args.ppapi = ppapi_;
451
452  ScopedFilesystem fs;
453  Error error = factory->second->CreateFilesystem(args, &fs);
454  if (error)
455    return error;
456
457  error = AttachFsAtPath(fs, abs_path);
458  if (error)
459    return error;
460
461  if (create_fs_node) {
462    error = CreateFsNode(fs);
463    if (error)
464      return error;
465  }
466
467  *out_filesystem = fs;
468  return 0;
469}
470
471Error KernelProxy::CreateFsNode(const ScopedFilesystem& fs) {
472  assert(dev_fs_);
473
474  return dev_fs_->CreateFsNode(fs.get());
475}
476
477int KernelProxy::umount(const char* path) {
478  ScopedFilesystem fs;
479  Error error = DetachFsAtPath(path, &fs);
480  if (error) {
481    errno = error;
482    return -1;
483  }
484
485  error = dev_fs_->DestroyFsNode(fs.get());
486  if (error) {
487    // Ignore any errors here, just log.
488    LOG_ERROR("Unable to destroy FsNode: %s", strerror(error));
489  }
490  return 0;
491}
492
493ssize_t KernelProxy::read(int fd, void* buf, size_t nbytes) {
494  ScopedKernelHandle handle;
495  Error error = AcquireHandle(fd, &handle);
496  if (error) {
497    errno = error;
498    return -1;
499  }
500
501  int cnt = 0;
502  error = handle->Read(buf, nbytes, &cnt);
503  if (error) {
504    errno = error;
505    return -1;
506  }
507
508  return cnt;
509}
510
511ssize_t KernelProxy::write(int fd, const void* buf, size_t nbytes) {
512  ScopedKernelHandle handle;
513  Error error = AcquireHandle(fd, &handle);
514  if (error) {
515    errno = error;
516    return -1;
517  }
518
519  int cnt = 0;
520  error = handle->Write(buf, nbytes, &cnt);
521  if (error) {
522    errno = error;
523    return -1;
524  }
525
526  return cnt;
527}
528
529int KernelProxy::fstat(int fd, struct stat* buf) {
530  ScopedKernelHandle handle;
531  Error error = AcquireHandle(fd, &handle);
532  if (error) {
533    errno = error;
534    return -1;
535  }
536
537  error = handle->node()->GetStat(buf);
538  if (error) {
539    errno = error;
540    return -1;
541  }
542
543  return 0;
544}
545
546int KernelProxy::getdents(int fd, void* buf, unsigned int count) {
547  ScopedKernelHandle handle;
548  Error error = AcquireHandle(fd, &handle);
549  if (error) {
550    errno = error;
551    return -1;
552  }
553
554  int cnt = 0;
555  error = handle->GetDents(static_cast<dirent*>(buf), count, &cnt);
556  if (error)
557    errno = error;
558
559  return cnt;
560}
561
562int KernelProxy::fchdir(int fd) {
563  ScopedKernelHandle handle;
564  std::string path;
565  Error error = AcquireHandleAndPath(fd, &handle, &path);
566  if (error) {
567    errno = error;
568    return -1;
569  }
570
571  if (!handle->node()->IsaDir()) {
572    errno = ENOTDIR;
573    return -1;
574  }
575
576  if (path.empty()) {
577    errno = EBADF;
578    return -1;
579  }
580
581  error = SetCWD(path);
582  if (error) {
583    // errno is return value from SetCWD
584    errno = error;
585    return -1;
586  }
587  return 0;
588}
589
590int KernelProxy::ftruncate(int fd, off_t length) {
591  ScopedKernelHandle handle;
592  Error error = AcquireHandle(fd, &handle);
593  if (error) {
594    errno = error;
595    return -1;
596  }
597
598  error = handle->node()->FTruncate(length);
599  if (error) {
600    errno = error;
601    return -1;
602  }
603
604  return 0;
605}
606
607int KernelProxy::fsync(int fd) {
608  ScopedKernelHandle handle;
609  Error error = AcquireHandle(fd, &handle);
610  if (error) {
611    errno = error;
612    return -1;
613  }
614
615  error = handle->node()->FSync();
616  if (error) {
617    errno = error;
618    return -1;
619  }
620
621  return 0;
622}
623
624int KernelProxy::fdatasync(int fd) {
625  errno = ENOSYS;
626  return -1;
627}
628
629int KernelProxy::isatty(int fd) {
630  ScopedKernelHandle handle;
631  Error error = AcquireHandle(fd, &handle);
632  if (error) {
633    errno = error;
634    return 0;
635  }
636
637  error = handle->node()->Isatty();
638  if (error) {
639    errno = error;
640    return 0;
641  }
642
643  return 1;
644}
645
646int KernelProxy::ioctl(int fd, int request, va_list args) {
647  ScopedKernelHandle handle;
648  Error error = AcquireHandle(fd, &handle);
649  if (error) {
650    errno = error;
651    return -1;
652  }
653
654  error = handle->node()->VIoctl(request, args);
655  if (error) {
656    errno = error;
657    return -1;
658  }
659
660  return 0;
661}
662
663off_t KernelProxy::lseek(int fd, off_t offset, int whence) {
664  ScopedKernelHandle handle;
665  Error error = AcquireHandle(fd, &handle);
666  if (error) {
667    errno = error;
668    return -1;
669  }
670
671  off_t new_offset;
672  error = handle->Seek(offset, whence, &new_offset);
673  if (error) {
674    errno = error;
675    return -1;
676  }
677
678  return new_offset;
679}
680
681int KernelProxy::unlink(const char* path) {
682  ScopedFilesystem fs;
683  Path rel;
684
685  Error error = AcquireFsAndRelPath(path, &fs, &rel);
686  if (error) {
687    errno = error;
688    return -1;
689  }
690
691  error = fs->Unlink(rel);
692  if (error) {
693    errno = error;
694    return -1;
695  }
696
697  return 0;
698}
699
700int KernelProxy::truncate(const char* path, off_t len) {
701  int fd = KernelProxy::open(path, O_WRONLY);
702  if (-1 == fd)
703    return -1;
704
705  int result = ftruncate(fd, len);
706  close(fd);
707  return result;
708}
709
710int KernelProxy::lstat(const char* path, struct stat* buf) {
711  return stat(path, buf);
712}
713
714int KernelProxy::rename(const char* path, const char* newpath) {
715  ScopedFilesystem fs;
716  Path rel;
717  Error error = AcquireFsAndRelPath(path, &fs, &rel);
718  if (error) {
719    errno = error;
720    return -1;
721  }
722
723  ScopedFilesystem newfs;
724  Path newrel;
725  error = AcquireFsAndRelPath(newpath, &newfs, &newrel);
726  if (error) {
727    errno = error;
728    return -1;
729  }
730
731  if (newfs.get() != fs.get()) {
732    // Renaming accross mountpoints is not allowed
733    errno = EXDEV;
734    return -1;
735  }
736
737  // They already point to the same path
738  if (rel == newrel)
739    return 0;
740
741  error = fs->Rename(rel, newrel);
742  if (error) {
743    errno = error;
744    return -1;
745  }
746
747  return 0;
748}
749
750int KernelProxy::remove(const char* path) {
751  ScopedFilesystem fs;
752  Path rel;
753
754  Error error = AcquireFsAndRelPath(path, &fs, &rel);
755  if (error) {
756    errno = error;
757    return -1;
758  }
759
760  error = fs->Remove(rel);
761  if (error) {
762    errno = error;
763    return -1;
764  }
765
766  return 0;
767}
768
769// TODO(noelallen): Needs implementation.
770int KernelProxy::fchmod(int fd, int mode) {
771  ScopedKernelHandle handle;
772  Error error = AcquireHandle(fd, &handle);
773  if (error) {
774    errno = error;
775    return -1;
776  }
777
778  return 0;
779}
780
781int KernelProxy::fcntl(int fd, int request, va_list args) {
782  Error error = 0;
783
784  // F_GETFD and F_SETFD are descriptor specific flags that
785  // are stored in the KernelObject's decriptor map unlike
786  // F_GETFL and F_SETFL which are handle specific.
787  switch (request) {
788    case F_GETFD: {
789      int rtn = -1;
790      error = GetFDFlags(fd, &rtn);
791      if (error) {
792        errno = error;
793        return -1;
794      }
795      return rtn;
796    }
797    case F_SETFD: {
798      int flags = va_arg(args, int);
799      error = SetFDFlags(fd, flags);
800      if (error) {
801        errno = error;
802        return -1;
803      }
804      return 0;
805    }
806  }
807
808  ScopedKernelHandle handle;
809  error = AcquireHandle(fd, &handle);
810  if (error) {
811    errno = error;
812    return -1;
813  }
814
815  int rtn = 0;
816  error = handle->VFcntl(request, &rtn, args);
817  if (error) {
818    errno = error;
819    return -1;
820  }
821
822  return rtn;
823}
824
825int KernelProxy::access(const char* path, int amode) {
826  ScopedFilesystem fs;
827  Path rel;
828
829  Error error = AcquireFsAndRelPath(path, &fs, &rel);
830  if (error) {
831    errno = error;
832    return -1;
833  }
834
835  error = fs->Access(rel, amode);
836  if (error) {
837    errno = error;
838    return -1;
839  }
840  return 0;
841}
842
843int KernelProxy::readlink(const char* path, char* buf, size_t count) {
844  errno = EINVAL;
845  return -1;
846}
847
848int KernelProxy::utimes(const char* filename, const struct timeval times[2]) {
849  errno = EINVAL;
850  return -1;
851}
852
853// TODO(noelallen): Needs implementation.
854int KernelProxy::link(const char* oldpath, const char* newpath) {
855  errno = EINVAL;
856  return -1;
857}
858
859int KernelProxy::symlink(const char* oldpath, const char* newpath) {
860  errno = EINVAL;
861  return -1;
862}
863
864void* KernelProxy::mmap(void* addr,
865                        size_t length,
866                        int prot,
867                        int flags,
868                        int fd,
869                        size_t offset) {
870  // We shouldn't be getting anonymous mmaps here.
871  assert((flags & MAP_ANONYMOUS) == 0);
872  assert(fd != -1);
873
874  ScopedKernelHandle handle;
875  Error error = AcquireHandle(fd, &handle);
876  if (error) {
877    errno = error;
878    return MAP_FAILED;
879  }
880
881  void* new_addr;
882  error = handle->node()->MMap(addr, length, prot, flags, offset, &new_addr);
883  if (error) {
884    errno = error;
885    return MAP_FAILED;
886  }
887
888  return new_addr;
889}
890
891int KernelProxy::munmap(void* addr, size_t length) {
892  // NOTE: The comment below is from a previous discarded implementation that
893  // tracks mmap'd regions. For simplicity, we no longer do this; because we
894  // "snapshot" the contents of the file in mmap(), and don't support
895  // write-back or updating the mapped region when the file is written, holding
896  // on to the KernelHandle is pointless.
897  //
898  // If we ever do, these threading issues should be considered.
899
900  //
901  // WARNING: this function may be called by free().
902  //
903  // There is a potential deadlock scenario:
904  // Thread 1: open() -> takes lock1 -> free() -> takes lock2
905  // Thread 2: free() -> takes lock2 -> munmap() -> takes lock1
906  //
907  // Note that open() above could be any function that takes a lock that is
908  // shared with munmap (this includes munmap!)
909  //
910  // To prevent this, we avoid taking locks in munmap() that are used by other
911  // nacl_io functions that may call free. Specifically, we only take the
912  // mmap_lock, which is only shared with mmap() above. There is still a
913  // possibility of deadlock if mmap() or munmap() calls free(), so this is not
914  // allowed.
915  //
916  // Unfortunately, munmap still needs to acquire other locks; see the call to
917  // ReleaseHandle below which takes the process lock. This is safe as long as
918  // this is never executed from free() -- we can be reasonably sure this is
919  // true, because malloc only makes anonymous mmap() requests, and should only
920  // be munmapping those allocations. We never add to mmap_info_list_ for
921  // anonymous maps, so the unmap_list should always be empty when called from
922  // free().
923  return 0;
924}
925
926int KernelProxy::tcflush(int fd, int queue_selector) {
927  ScopedKernelHandle handle;
928  Error error = AcquireHandle(fd, &handle);
929  if (error) {
930    errno = error;
931    return -1;
932  }
933
934  error = handle->node()->Tcflush(queue_selector);
935  if (error) {
936    errno = error;
937    return -1;
938  }
939
940  return 0;
941}
942
943int KernelProxy::tcgetattr(int fd, struct termios* termios_p) {
944  ScopedKernelHandle handle;
945  Error error = AcquireHandle(fd, &handle);
946  if (error) {
947    errno = error;
948    return -1;
949  }
950
951  error = handle->node()->Tcgetattr(termios_p);
952  if (error) {
953    errno = error;
954    return -1;
955  }
956
957  return 0;
958}
959
960int KernelProxy::tcsetattr(int fd,
961                           int optional_actions,
962                           const struct termios* termios_p) {
963  ScopedKernelHandle handle;
964  Error error = AcquireHandle(fd, &handle);
965  if (error) {
966    errno = error;
967    return -1;
968  }
969
970  error = handle->node()->Tcsetattr(optional_actions, termios_p);
971  if (error) {
972    errno = error;
973    return -1;
974  }
975
976  return 0;
977}
978
979int KernelProxy::kill(pid_t pid, int sig) {
980  // Currently we don't even pretend that other processes exist
981  // so we can only send a signal to outselves.  For kill(2)
982  // pid 0 means the current process group and -1 means all the
983  // processes we have permission to send signals to.
984  if (pid != getpid() && pid != -1 && pid != 0) {
985    errno = ESRCH;
986    return -1;
987  }
988
989  // Raise an event so that select/poll get interrupted.
990  AUTO_LOCK(signal_emitter_->GetLock())
991  signal_emitter_->RaiseEvents_Locked(POLLERR);
992  switch (sig) {
993    case SIGWINCH:
994      if (sigwinch_handler_.sa_handler != SIG_IGN &&
995          sigwinch_handler_.sa_handler != SIG_DFL) {
996        sigwinch_handler_.sa_handler(SIGWINCH);
997      }
998      break;
999
1000    case SIGUSR1:
1001    case SIGUSR2:
1002      break;
1003
1004    default:
1005      errno = EINVAL;
1006      return -1;
1007  }
1008  return 0;
1009}
1010
1011int KernelProxy::sigaction(int signum,
1012                           const struct sigaction* action,
1013                           struct sigaction* oaction) {
1014  if (action && action->sa_flags & SA_SIGINFO) {
1015    // We don't support SA_SIGINFO (sa_sigaction field) yet
1016    errno = EINVAL;
1017    return -1;
1018  }
1019
1020  switch (signum) {
1021    // Handled signals.
1022    case SIGWINCH: {
1023      if (oaction)
1024        *oaction = sigwinch_handler_;
1025      if (action) {
1026        sigwinch_handler_ = *action;
1027      }
1028      return 0;
1029    }
1030
1031    // Known signals
1032    case SIGHUP:
1033    case SIGINT:
1034    case SIGPIPE:
1035    case SIGPOLL:
1036    case SIGPROF:
1037    case SIGTERM:
1038    case SIGCHLD:
1039    case SIGURG:
1040    case SIGFPE:
1041    case SIGILL:
1042    case SIGQUIT:
1043    case SIGSEGV:
1044    case SIGTRAP:
1045      if (action && action->sa_handler != SIG_DFL) {
1046        // Trying to set this action to anything other than SIG_DFL
1047        // is not yet supported.
1048        errno = EINVAL;
1049        return -1;
1050      }
1051
1052      if (oaction) {
1053        memset(oaction, 0, sizeof(*oaction));
1054        oaction->sa_handler = SIG_DFL;
1055      }
1056      return 0;
1057
1058    // KILL and STOP cannot be handled
1059    case SIGKILL:
1060    case SIGSTOP:
1061      errno = EINVAL;
1062      return -1;
1063  }
1064
1065  // Unknown signum
1066  errno = EINVAL;
1067  return -1;
1068}
1069
1070#ifdef PROVIDES_SOCKET_API
1071
1072int KernelProxy::select(int nfds,
1073                        fd_set* readfds,
1074                        fd_set* writefds,
1075                        fd_set* exceptfds,
1076                        struct timeval* timeout) {
1077  std::vector<pollfd> pollfds;
1078
1079  for (int fd = 0; fd < nfds; fd++) {
1080    int events = 0;
1081    if (readfds && FD_ISSET(fd, readfds)) {
1082      events |= POLLIN;
1083      FD_CLR(fd, readfds);
1084    }
1085
1086    if (writefds && FD_ISSET(fd, writefds)) {
1087      events |= POLLOUT;
1088      FD_CLR(fd, writefds);
1089    }
1090
1091    if (exceptfds && FD_ISSET(fd, exceptfds)) {
1092      events |= POLLERR | POLLHUP;
1093      FD_CLR(fd, exceptfds);
1094    }
1095
1096    if (events) {
1097      pollfd info;
1098      info.fd = fd;
1099      info.events = events;
1100      pollfds.push_back(info);
1101    }
1102  }
1103
1104  // NULL timeout signals wait forever.
1105  int ms_timeout = -1;
1106  if (timeout != NULL) {
1107    int64_t ms = timeout->tv_sec * 1000 + ((timeout->tv_usec + 500) / 1000);
1108
1109    // If the timeout is invalid or too long (larger than signed 32 bit).
1110    if ((timeout->tv_sec < 0) || (timeout->tv_sec >= (INT_MAX / 1000)) ||
1111        (timeout->tv_usec < 0) || (timeout->tv_usec >= 1000000) || (ms < 0) ||
1112        (ms >= INT_MAX)) {
1113      errno = EINVAL;
1114      return -1;
1115    }
1116
1117    ms_timeout = static_cast<int>(ms);
1118  }
1119
1120  int result = poll(&pollfds[0], pollfds.size(), ms_timeout);
1121  if (result == -1)
1122    return -1;
1123
1124  int event_cnt = 0;
1125  for (size_t index = 0; index < pollfds.size(); index++) {
1126    pollfd* info = &pollfds[index];
1127    if (info->revents & POLLIN) {
1128      FD_SET(info->fd, readfds);
1129      event_cnt++;
1130    }
1131    if (info->revents & POLLOUT) {
1132      FD_SET(info->fd, writefds);
1133      event_cnt++;
1134    }
1135    if (info->revents & (POLLHUP | POLLERR)) {
1136      FD_SET(info->fd, exceptfds);
1137      event_cnt++;
1138    }
1139  }
1140
1141  return event_cnt;
1142}
1143
1144struct PollInfo {
1145  PollInfo() : index(-1) {};
1146
1147  std::vector<struct pollfd*> fds;
1148  int index;
1149};
1150
1151typedef std::map<EventEmitter*, PollInfo> EventPollMap_t;
1152
1153int KernelProxy::poll(struct pollfd* fds, nfds_t nfds, int timeout) {
1154  EventPollMap_t event_map;
1155
1156  std::vector<EventRequest> requests;
1157  size_t event_cnt = 0;
1158
1159  for (int index = 0; static_cast<nfds_t>(index) < nfds; index++) {
1160    ScopedKernelHandle handle;
1161    struct pollfd* fd_info = &fds[index];
1162    Error err = AcquireHandle(fd_info->fd, &handle);
1163
1164    fd_info->revents = 0;
1165
1166    // If the node isn't open, or somehow invalid, mark it so.
1167    if (err != 0) {
1168      fd_info->revents = POLLNVAL;
1169      event_cnt++;
1170      continue;
1171    }
1172
1173    // If it's already signaled, then just capture the event
1174    ScopedEventEmitter emitter(handle->node()->GetEventEmitter());
1175    int events = POLLIN | POLLOUT;
1176    if (emitter)
1177      events = emitter->GetEventStatus();
1178
1179    if (events & fd_info->events) {
1180      fd_info->revents = events & fd_info->events;
1181      event_cnt++;
1182      continue;
1183    }
1184
1185    if (NULL == emitter) {
1186      fd_info->revents = POLLNVAL;
1187      event_cnt++;
1188      continue;
1189    }
1190
1191    // Otherwise try to track it.
1192    PollInfo* info = &event_map[emitter.get()];
1193    if (info->index == -1) {
1194      EventRequest request;
1195      request.emitter = emitter;
1196      request.filter = fd_info->events;
1197      request.events = 0;
1198
1199      info->index = requests.size();
1200      requests.push_back(request);
1201    }
1202    info->fds.push_back(fd_info);
1203    requests[info->index].filter |= fd_info->events;
1204  }
1205
1206  // If nothing is signaled, then we must wait on the event map
1207  if (0 == event_cnt) {
1208    EventListenerPoll wait;
1209    Error err = wait.WaitOnAny(&requests[0], requests.size(), timeout);
1210    if ((err != 0) && (err != ETIMEDOUT)) {
1211      errno = err;
1212      return -1;
1213    }
1214
1215    for (size_t rindex = 0; rindex < requests.size(); rindex++) {
1216      EventRequest* request = &requests[rindex];
1217      if (request->events) {
1218        PollInfo* poll_info = &event_map[request->emitter.get()];
1219        for (size_t findex = 0; findex < poll_info->fds.size(); findex++) {
1220          struct pollfd* fd_info = poll_info->fds[findex];
1221          uint32_t events = fd_info->events & request->events;
1222          if (events) {
1223            fd_info->revents = events;
1224            event_cnt++;
1225          }
1226        }
1227      }
1228    }
1229  }
1230
1231  return event_cnt;
1232}
1233
1234// Socket Functions
1235int KernelProxy::accept(int fd, struct sockaddr* addr, socklen_t* len) {
1236  if (NULL == addr || NULL == len) {
1237    errno = EFAULT;
1238    return -1;
1239  }
1240
1241  ScopedKernelHandle handle;
1242  Error error = AcquireHandle(fd, &handle);
1243  if (error) {
1244    errno = error;
1245    return -1;
1246  }
1247
1248  PP_Resource new_sock = 0;
1249  error = handle->Accept(&new_sock, addr, len);
1250  if (error != 0) {
1251    errno = error;
1252    return -1;
1253  }
1254
1255  SocketNode* sock = new TcpNode(stream_fs_.get(), new_sock);
1256
1257  // The SocketNode now holds a reference to the new socket
1258  // so we release ours.
1259  ppapi_->ReleaseResource(new_sock);
1260  error = sock->Init(O_RDWR);
1261  if (error != 0) {
1262    errno = error;
1263    return -1;
1264  }
1265
1266  ScopedNode node(sock);
1267  ScopedKernelHandle new_handle(new KernelHandle(stream_fs_, node));
1268  error = new_handle->Init(O_RDWR);
1269  if (error != 0) {
1270    errno = error;
1271    return -1;
1272  }
1273
1274  return AllocateFD(new_handle);
1275}
1276
1277int KernelProxy::bind(int fd, const struct sockaddr* addr, socklen_t len) {
1278  if (NULL == addr) {
1279    errno = EFAULT;
1280    return -1;
1281  }
1282
1283  ScopedKernelHandle handle;
1284  if (AcquireSocketHandle(fd, &handle) == -1)
1285    return -1;
1286
1287  Error err = handle->socket_node()->Bind(addr, len);
1288  if (err != 0) {
1289    errno = err;
1290    return -1;
1291  }
1292
1293  return 0;
1294}
1295
1296int KernelProxy::connect(int fd, const struct sockaddr* addr, socklen_t len) {
1297  if (NULL == addr) {
1298    errno = EFAULT;
1299    return -1;
1300  }
1301
1302  ScopedKernelHandle handle;
1303  Error error = AcquireHandle(fd, &handle);
1304  if (error) {
1305    errno = error;
1306    return -1;
1307  }
1308
1309  error = handle->Connect(addr, len);
1310  if (error != 0) {
1311    errno = error;
1312    return -1;
1313  }
1314
1315  return 0;
1316}
1317
1318void KernelProxy::freeaddrinfo(struct addrinfo* res) {
1319  return host_resolver_.freeaddrinfo(res);
1320}
1321
1322int KernelProxy::getaddrinfo(const char* node,
1323                             const char* service,
1324                             const struct addrinfo* hints,
1325                             struct addrinfo** res) {
1326  return host_resolver_.getaddrinfo(node, service, hints, res);
1327}
1328
1329struct hostent* KernelProxy::gethostbyname(const char* name) {
1330  return host_resolver_.gethostbyname(name);
1331}
1332
1333int KernelProxy::getpeername(int fd, struct sockaddr* addr, socklen_t* len) {
1334  if (NULL == addr || NULL == len) {
1335    errno = EFAULT;
1336    return -1;
1337  }
1338
1339  ScopedKernelHandle handle;
1340  if (AcquireSocketHandle(fd, &handle) == -1)
1341    return -1;
1342
1343  Error err = handle->socket_node()->GetPeerName(addr, len);
1344  if (err != 0) {
1345    errno = err;
1346    return -1;
1347  }
1348
1349  return 0;
1350}
1351
1352int KernelProxy::getsockname(int fd, struct sockaddr* addr, socklen_t* len) {
1353  if (NULL == addr || NULL == len) {
1354    errno = EFAULT;
1355    return -1;
1356  }
1357
1358  ScopedKernelHandle handle;
1359  if (AcquireSocketHandle(fd, &handle) == -1)
1360    return -1;
1361
1362  Error err = handle->socket_node()->GetSockName(addr, len);
1363  if (err != 0) {
1364    errno = err;
1365    return -1;
1366  }
1367
1368  return 0;
1369}
1370
1371int KernelProxy::getsockopt(int fd,
1372                            int lvl,
1373                            int optname,
1374                            void* optval,
1375                            socklen_t* len) {
1376  if (NULL == optval || NULL == len) {
1377    errno = EFAULT;
1378    return -1;
1379  }
1380
1381  ScopedKernelHandle handle;
1382  if (AcquireSocketHandle(fd, &handle) == -1)
1383    return -1;
1384
1385  Error err = handle->socket_node()->GetSockOpt(lvl, optname, optval, len);
1386  if (err != 0) {
1387    errno = err;
1388    return -1;
1389  }
1390
1391  return 0;
1392}
1393
1394int KernelProxy::listen(int fd, int backlog) {
1395  ScopedKernelHandle handle;
1396  if (AcquireSocketHandle(fd, &handle) == -1)
1397    return -1;
1398
1399  Error err = handle->socket_node()->Listen(backlog);
1400  if (err != 0) {
1401    errno = err;
1402    return -1;
1403  }
1404
1405  return 0;
1406}
1407
1408ssize_t KernelProxy::recv(int fd, void* buf, size_t len, int flags) {
1409  if (NULL == buf) {
1410    errno = EFAULT;
1411    return -1;
1412  }
1413
1414  ScopedKernelHandle handle;
1415  Error error = AcquireHandle(fd, &handle);
1416  if (error) {
1417    errno = error;
1418    return -1;
1419  }
1420
1421  int out_len = 0;
1422  error = handle->Recv(buf, len, flags, &out_len);
1423  if (error != 0) {
1424    errno = error;
1425    return -1;
1426  }
1427
1428  return static_cast<ssize_t>(out_len);
1429}
1430
1431ssize_t KernelProxy::recvfrom(int fd,
1432                              void* buf,
1433                              size_t len,
1434                              int flags,
1435                              struct sockaddr* addr,
1436                              socklen_t* addrlen) {
1437  // According to the manpage, recvfrom with a null addr is identical to recv.
1438  if (NULL == addr) {
1439    return recv(fd, buf, len, flags);
1440  }
1441
1442  if (NULL == buf || NULL == addrlen) {
1443    errno = EFAULT;
1444    return -1;
1445  }
1446
1447  ScopedKernelHandle handle;
1448  Error error = AcquireHandle(fd, &handle);
1449  if (error) {
1450    errno = error;
1451    return -1;
1452  }
1453
1454  int out_len = 0;
1455  error = handle->RecvFrom(buf, len, flags, addr, addrlen, &out_len);
1456  if (error != 0) {
1457    errno = error;
1458    return -1;
1459  }
1460
1461  return static_cast<ssize_t>(out_len);
1462}
1463
1464ssize_t KernelProxy::recvmsg(int fd, struct msghdr* msg, int flags) {
1465  if (NULL == msg) {
1466    errno = EFAULT;
1467    return -1;
1468  }
1469
1470  ScopedKernelHandle handle;
1471  if (AcquireSocketHandle(fd, &handle) == -1)
1472    return -1;
1473
1474  errno = EOPNOTSUPP;
1475  return -1;
1476}
1477
1478ssize_t KernelProxy::send(int fd, const void* buf, size_t len, int flags) {
1479  if (NULL == buf) {
1480    errno = EFAULT;
1481    return -1;
1482  }
1483
1484  ScopedKernelHandle handle;
1485  Error error = AcquireHandle(fd, &handle);
1486  if (error) {
1487    errno = error;
1488    return -1;
1489  }
1490
1491  int out_len = 0;
1492  error = handle->Send(buf, len, flags, &out_len);
1493  if (error != 0) {
1494    errno = error;
1495    return -1;
1496  }
1497
1498  return static_cast<ssize_t>(out_len);
1499}
1500
1501ssize_t KernelProxy::sendto(int fd,
1502                            const void* buf,
1503                            size_t len,
1504                            int flags,
1505                            const struct sockaddr* addr,
1506                            socklen_t addrlen) {
1507  // According to the manpage, sendto with a null addr is identical to send.
1508  if (NULL == addr) {
1509    return send(fd, buf, len, flags);
1510  }
1511
1512  if (NULL == buf) {
1513    errno = EFAULT;
1514    return -1;
1515  }
1516
1517  ScopedKernelHandle handle;
1518  Error error = AcquireHandle(fd, &handle);
1519  if (error) {
1520    errno = error;
1521    return -1;
1522  }
1523
1524  int out_len = 0;
1525  error = handle->SendTo(buf, len, flags, addr, addrlen, &out_len);
1526  if (error != 0) {
1527    errno = error;
1528    return -1;
1529  }
1530
1531  return static_cast<ssize_t>(out_len);
1532}
1533
1534ssize_t KernelProxy::sendmsg(int fd, const struct msghdr* msg, int flags) {
1535  if (NULL == msg) {
1536    errno = EFAULT;
1537    return -1;
1538  }
1539
1540  ScopedKernelHandle handle;
1541  if (AcquireSocketHandle(fd, &handle) == -1)
1542    return -1;
1543
1544  errno = EOPNOTSUPP;
1545  return -1;
1546}
1547
1548int KernelProxy::setsockopt(int fd,
1549                            int lvl,
1550                            int optname,
1551                            const void* optval,
1552                            socklen_t len) {
1553  if (NULL == optval) {
1554    errno = EFAULT;
1555    return -1;
1556  }
1557
1558  ScopedKernelHandle handle;
1559  if (AcquireSocketHandle(fd, &handle) == -1)
1560    return -1;
1561
1562  Error err = handle->socket_node()->SetSockOpt(lvl, optname, optval, len);
1563  if (err != 0) {
1564    errno = err;
1565    return -1;
1566  }
1567
1568  return 0;
1569}
1570
1571int KernelProxy::shutdown(int fd, int how) {
1572  ScopedKernelHandle handle;
1573  if (AcquireSocketHandle(fd, &handle) == -1)
1574    return -1;
1575
1576  Error err = handle->socket_node()->Shutdown(how);
1577  if (err != 0) {
1578    errno = err;
1579    return -1;
1580  }
1581
1582  return 0;
1583}
1584
1585int KernelProxy::socket(int domain, int type, int protocol) {
1586  if (AF_INET != domain && AF_INET6 != domain) {
1587    errno = EAFNOSUPPORT;
1588    return -1;
1589  }
1590
1591  int open_flags = O_RDWR;
1592
1593  if (type & SOCK_CLOEXEC) {
1594#ifdef O_CLOEXEC
1595    // The NaCl newlib version of fcntl.h doesn't currently define
1596    // O_CLOEXEC.
1597    // TODO(sbc): remove this guard once it gets added.
1598    open_flags |= O_CLOEXEC;
1599#endif
1600    type &= ~SOCK_CLOEXEC;
1601  }
1602
1603  if (type & SOCK_NONBLOCK) {
1604    open_flags |= O_NONBLOCK;
1605    type &= ~SOCK_NONBLOCK;
1606  }
1607
1608  SocketNode* sock = NULL;
1609  switch (type) {
1610    case SOCK_DGRAM:
1611      sock = new UdpNode(stream_fs_.get());
1612      break;
1613
1614    case SOCK_STREAM:
1615      sock = new TcpNode(stream_fs_.get());
1616      break;
1617
1618    case SOCK_SEQPACKET:
1619    case SOCK_RDM:
1620    case SOCK_RAW:
1621      errno = EPROTONOSUPPORT;
1622      return -1;
1623
1624    default:
1625      errno = EINVAL;
1626      return -1;
1627  }
1628
1629  ScopedNode node(sock);
1630  Error rtn = sock->Init(O_RDWR);
1631  if (rtn != 0) {
1632    errno = rtn;
1633    return -1;
1634  }
1635
1636  ScopedKernelHandle handle(new KernelHandle(stream_fs_, node));
1637  rtn = handle->Init(open_flags);
1638  if (rtn != 0) {
1639    errno = rtn;
1640    return -1;
1641  }
1642
1643  return AllocateFD(handle);
1644}
1645
1646int KernelProxy::socketpair(int domain, int type, int protocol, int* sv) {
1647  if (NULL == sv) {
1648    errno = EFAULT;
1649    return -1;
1650  }
1651
1652  // Catch-22: We don't support AF_UNIX, but any other AF doesn't support
1653  // socket pairs. Thus, this function always fails.
1654  if (AF_UNIX != domain) {
1655    errno = EPROTONOSUPPORT;
1656    return -1;
1657  }
1658
1659  if (AF_INET != domain && AF_INET6 != domain) {
1660    errno = EAFNOSUPPORT;
1661    return -1;
1662  }
1663
1664  // We cannot reach this point.
1665  errno = ENOSYS;
1666  return -1;
1667}
1668
1669int KernelProxy::AcquireSocketHandle(int fd, ScopedKernelHandle* handle) {
1670  Error error = AcquireHandle(fd, handle);
1671
1672  if (error) {
1673    errno = error;
1674    return -1;
1675  }
1676
1677  if ((handle->get()->node_->GetType() & S_IFSOCK) == 0) {
1678    errno = ENOTSOCK;
1679    return -1;
1680  }
1681
1682  return 0;
1683}
1684
1685#endif  // PROVIDES_SOCKET_API
1686
1687}  // namespace_nacl_io
1688