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