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