1ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// Use of this source code is governed by a BSD-style license that can be
3ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch// found in the LICENSE file.
4ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "nacl_io/mount_passthrough.h"
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <errno.h>
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "nacl_io/kernel_wrap_real.h"
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
9ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochnamespace nacl_io {
10ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class MountNodePassthrough : public MountNode {
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  explicit MountNodePassthrough(Mount* mount, int real_fd)
14868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      : MountNode(mount), real_fd_(real_fd) {}
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) protected:
17868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  virtual Error Init(int flags) { return 0; }
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void Destroy() {
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (real_fd_)
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      _real_close(real_fd_);
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    real_fd_ = 0;
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Normal read/write operations on a file
27868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  virtual Error Read(size_t offs, void* buf, size_t count, int* out_bytes) {
28868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    *out_bytes = 0;
29868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    off_t new_offset;
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int err = _real_lseek(real_fd_, offs, 0, &new_offset);
32868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (err)
33868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      return err;
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    size_t nread;
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    err = _real_read(real_fd_, buf, count, &nread);
37868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (err)
38868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      return err;
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
40868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    *out_bytes = static_cast<int>(nread);
41868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return 0;
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
44868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  virtual Error Write(size_t offs,
45868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                      const void* buf,
46868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                      size_t count,
47868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                      int* out_bytes) {
48868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    *out_bytes = 0;
49868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    off_t new_offset;
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int err = _real_lseek(real_fd_, offs, 0, &new_offset);
52868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (err)
53868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      return err;
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    size_t nwrote;
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    err = _real_write(real_fd_, buf, count, &nwrote);
57868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (err)
58868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      return err;
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
60868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    *out_bytes = static_cast<int>(nwrote);
61868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return 0;
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
64868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  virtual Error FTruncate(off_t size) {
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // TODO(binji): what to do here?
66868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return ENOSYS;
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
69ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch  virtual Error GetDents(size_t offs,
70ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch                         struct dirent* pdir,
71ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch                         size_t count,
72ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch                         int* out_bytes) {
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    size_t nread;
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int err = _real_getdents(real_fd_, pdir, count, &nread);
75868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (err)
76868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      return err;
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return nread;
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
80868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  virtual Error GetStat(struct stat* stat) {
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    int err = _real_fstat(real_fd_, stat);
82868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (err)
83868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      return err;
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return 0;
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
87868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  Error MMap(void* addr,
88868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)             size_t length,
89868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)             int prot,
90868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)             int flags,
91868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)             size_t offset,
92868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)             void** out_addr) {
93868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    *out_addr = addr;
94868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    int err = _real_mmap(out_addr, length, prot, flags, real_fd_, offset);
95868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (err)
96868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      return err;
97868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return 0;
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  friend class MountPassthrough;
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int real_fd_;
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
106868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)MountPassthrough::MountPassthrough() {}
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
108868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)Error MountPassthrough::Init(int dev,
109868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                             StringMap_t& args,
110868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                             PepperInterface* ppapi) {
111868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return Mount::Init(dev, args, ppapi);
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
114868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void MountPassthrough::Destroy() {}
115868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
116eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochError MountPassthrough::Access(const Path& path, int a_mode) {
117eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // There is no underlying 'access' syscall in NaCl. It just returns ENOSYS.
118eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  return ENOSYS;
119eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
121eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochError MountPassthrough::Open(const Path& path,
122eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                             int mode,
123eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                             ScopedMountNode* out_node) {
124eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  out_node->reset(NULL);
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int real_fd;
126868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  int error = _real_open(path.Join().c_str(), mode, 0666, &real_fd);
127868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (error)
128868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return error;
1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
130eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  out_node->reset(new MountNodePassthrough(this, real_fd));
131868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return 0;
1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
134eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochError MountPassthrough::OpenResource(const Path& path,
135eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                                     ScopedMountNode* out_node) {
1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int real_fd;
137eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  out_node->reset(NULL);
138868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  int error = _real_open_resource(path.Join().c_str(), &real_fd);
139868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (error)
140868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return error;
1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
142eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  out_node->reset(new MountNodePassthrough(this, real_fd));
143868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return 0;
1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
146868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)Error MountPassthrough::Unlink(const Path& path) {
1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Not implemented by NaCl.
148868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return ENOSYS;
1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
151868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)Error MountPassthrough::Mkdir(const Path& path, int perm) {
152868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return _real_mkdir(path.Join().c_str(), perm);
1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
155868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)Error MountPassthrough::Rmdir(const Path& path) {
156868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return _real_rmdir(path.Join().c_str());
1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
159868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)Error MountPassthrough::Remove(const Path& path) {
1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Not implemented by NaCl.
161868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return ENOSYS;
1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
163eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
164ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch}  // namespace nacl_io
165ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
166