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