Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / native_client_sdk / src / libraries / nacl_io / passthroughfs / passthrough_fs.cc
1 // Copyright 2013 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/passthroughfs/passthrough_fs.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 PassthroughFsNode : public Node {
15  public:
16   explicit PassthroughFsNode(Filesystem* filesystem, int real_fd)
17       : Node(filesystem), 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     int64_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     int64_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   virtual Error Isatty() {
94 #ifdef __GLIBC__
95     // isatty is not yet hooked up to the IRT interface under glibc.
96     return ENOTTY;
97 #else
98     int result = 0;
99     int err = _real_isatty(real_fd_, &result);
100     if (err)
101       return err;
102     return 0;
103 #endif
104   }
105
106   Error MMap(void* addr,
107              size_t length,
108              int prot,
109              int flags,
110              size_t offset,
111              void** out_addr) {
112     *out_addr = addr;
113     int err = _real_mmap(out_addr, length, prot, flags, real_fd_, offset);
114     if (err)
115       return err;
116     return 0;
117   }
118
119  private:
120   friend class PassthroughFs;
121
122   int real_fd_;
123 };
124
125 PassthroughFs::PassthroughFs() {}
126
127 Error PassthroughFs::Init(const FsInitArgs& args) {
128   return Filesystem::Init(args);
129 }
130
131 void PassthroughFs::Destroy() {}
132
133 Error PassthroughFs::Access(const Path& path, int a_mode) {
134   // There is no underlying 'access' syscall in NaCl. It just returns ENOSYS.
135   return ENOSYS;
136 }
137
138 Error PassthroughFs::Open(const Path& path, int mode, ScopedNode* out_node) {
139   out_node->reset(NULL);
140   int real_fd;
141   int error = _real_open(path.Join().c_str(), mode, 0666, &real_fd);
142   if (error)
143     return error;
144
145   out_node->reset(new PassthroughFsNode(this, real_fd));
146   return 0;
147 }
148
149 Error PassthroughFs::OpenResource(const Path& path, ScopedNode* out_node) {
150   int real_fd;
151   out_node->reset(NULL);
152   int error = _real_open_resource(path.Join().c_str(), &real_fd);
153   if (error)
154     return error;
155
156   out_node->reset(new PassthroughFsNode(this, real_fd));
157   return 0;
158 }
159
160 Error PassthroughFs::Unlink(const Path& path) {
161   // Not implemented by NaCl.
162   return ENOSYS;
163 }
164
165 Error PassthroughFs::Mkdir(const Path& path, int perm) {
166   return _real_mkdir(path.Join().c_str(), perm);
167 }
168
169 Error PassthroughFs::Rmdir(const Path& path) {
170   return _real_rmdir(path.Join().c_str());
171 }
172
173 Error PassthroughFs::Remove(const Path& path) {
174   // Not implemented by NaCl.
175   return ENOSYS;
176 }
177
178 Error PassthroughFs::Rename(const Path& path, const Path& newpath) {
179   // Not implemented by NaCl.
180   return ENOSYS;
181 }
182
183 }  // namespace nacl_io