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