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/mount_passthrough.h"
      6 #include <errno.h>
      7 #include "nacl_io/kernel_wrap_real.h"
      8 
      9 namespace nacl_io {
     10 
     11 class MountNodePassthrough : public MountNode {
     12  public:
     13   explicit MountNodePassthrough(Mount* mount, int real_fd)
     14       : MountNode(mount), real_fd_(real_fd) {}
     15 
     16  protected:
     17   virtual Error Init(int flags) { return 0; }
     18 
     19   virtual void Destroy() {
     20     if (real_fd_)
     21       _real_close(real_fd_);
     22     real_fd_ = 0;
     23   }
     24 
     25  public:
     26   // Normal read/write operations on a file
     27   virtual Error Read(size_t offs, void* buf, size_t count, int* out_bytes) {
     28     *out_bytes = 0;
     29 
     30     off_t new_offset;
     31     int err = _real_lseek(real_fd_, offs, 0, &new_offset);
     32     if (err)
     33       return err;
     34 
     35     size_t nread;
     36     err = _real_read(real_fd_, buf, count, &nread);
     37     if (err)
     38       return err;
     39 
     40     *out_bytes = static_cast<int>(nread);
     41     return 0;
     42   }
     43 
     44   virtual Error Write(size_t offs,
     45                       const void* buf,
     46                       size_t count,
     47                       int* out_bytes) {
     48     *out_bytes = 0;
     49 
     50     off_t new_offset;
     51     int err = _real_lseek(real_fd_, offs, 0, &new_offset);
     52     if (err)
     53       return err;
     54 
     55     size_t nwrote;
     56     err = _real_write(real_fd_, buf, count, &nwrote);
     57     if (err)
     58       return err;
     59 
     60     *out_bytes = static_cast<int>(nwrote);
     61     return 0;
     62   }
     63 
     64   virtual Error FTruncate(off_t size) {
     65     // TODO(binji): what to do here?
     66     return ENOSYS;
     67   }
     68 
     69   virtual Error GetDents(size_t offs,
     70                          struct dirent* pdir,
     71                          size_t count,
     72                          int* out_bytes) {
     73     size_t nread;
     74     int err = _real_getdents(real_fd_, pdir, count, &nread);
     75     if (err)
     76       return err;
     77     return nread;
     78   }
     79 
     80   virtual Error GetStat(struct stat* stat) {
     81     int err = _real_fstat(real_fd_, stat);
     82     if (err)
     83       return err;
     84     return 0;
     85   }
     86 
     87   Error MMap(void* addr,
     88              size_t length,
     89              int prot,
     90              int flags,
     91              size_t offset,
     92              void** out_addr) {
     93     *out_addr = addr;
     94     int err = _real_mmap(out_addr, length, prot, flags, real_fd_, offset);
     95     if (err)
     96       return err;
     97     return 0;
     98   }
     99 
    100  private:
    101   friend class MountPassthrough;
    102 
    103   int real_fd_;
    104 };
    105 
    106 MountPassthrough::MountPassthrough() {}
    107 
    108 Error MountPassthrough::Init(int dev,
    109                              StringMap_t& args,
    110                              PepperInterface* ppapi) {
    111   return Mount::Init(dev, args, ppapi);
    112 }
    113 
    114 void MountPassthrough::Destroy() {}
    115 
    116 Error MountPassthrough::Access(const Path& path, int a_mode) {
    117   // There is no underlying 'access' syscall in NaCl. It just returns ENOSYS.
    118   return ENOSYS;
    119 }
    120 
    121 Error MountPassthrough::Open(const Path& path,
    122                              int mode,
    123                              ScopedMountNode* out_node) {
    124   out_node->reset(NULL);
    125   int real_fd;
    126   int error = _real_open(path.Join().c_str(), mode, 0666, &real_fd);
    127   if (error)
    128     return error;
    129 
    130   out_node->reset(new MountNodePassthrough(this, real_fd));
    131   return 0;
    132 }
    133 
    134 Error MountPassthrough::OpenResource(const Path& path,
    135                                      ScopedMountNode* out_node) {
    136   int real_fd;
    137   out_node->reset(NULL);
    138   int error = _real_open_resource(path.Join().c_str(), &real_fd);
    139   if (error)
    140     return error;
    141 
    142   out_node->reset(new MountNodePassthrough(this, real_fd));
    143   return 0;
    144 }
    145 
    146 Error MountPassthrough::Unlink(const Path& path) {
    147   // Not implemented by NaCl.
    148   return ENOSYS;
    149 }
    150 
    151 Error MountPassthrough::Mkdir(const Path& path, int perm) {
    152   return _real_mkdir(path.Join().c_str(), perm);
    153 }
    154 
    155 Error MountPassthrough::Rmdir(const Path& path) {
    156   return _real_rmdir(path.Join().c_str());
    157 }
    158 
    159 Error MountPassthrough::Remove(const Path& path) {
    160   // Not implemented by NaCl.
    161   return ENOSYS;
    162 }
    163 
    164 }  // namespace nacl_io
    165 
    166