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