OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "nacl_io/passthroughfs/passthrough_fs.h" | 5 #include "nacl_io/passthroughfs/passthrough_fs.h" |
6 | 6 |
7 #include <errno.h> | 7 #include <errno.h> |
8 | 8 |
9 #include "nacl_io/kernel_handle.h" | 9 #include "nacl_io/kernel_handle.h" |
10 #include "nacl_io/kernel_wrap_real.h" | 10 #include "nacl_io/kernel_wrap_real.h" |
| 11 #include "nacl_io/passthroughfs/real_node.h" |
11 | 12 |
12 namespace nacl_io { | 13 namespace nacl_io { |
13 | 14 |
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() { | 15 PassthroughFs::PassthroughFs() { |
126 } | 16 } |
127 | 17 |
128 Error PassthroughFs::Init(const FsInitArgs& args) { | 18 Error PassthroughFs::Init(const FsInitArgs& args) { |
129 return Filesystem::Init(args); | 19 return Filesystem::Init(args); |
130 } | 20 } |
131 | 21 |
132 void PassthroughFs::Destroy() { | 22 void PassthroughFs::Destroy() { |
133 } | 23 } |
134 | 24 |
135 Error PassthroughFs::Access(const Path& path, int a_mode) { | 25 Error PassthroughFs::Access(const Path& path, int a_mode) { |
136 // There is no underlying 'access' syscall in NaCl. It just returns ENOSYS. | 26 // There is no underlying 'access' syscall in NaCl. It just returns ENOSYS. |
137 return ENOSYS; | 27 return ENOSYS; |
138 } | 28 } |
139 | 29 |
140 Error PassthroughFs::Open(const Path& path, int mode, ScopedNode* out_node) { | 30 Error PassthroughFs::Open(const Path& path, int mode, ScopedNode* out_node) { |
141 out_node->reset(NULL); | 31 out_node->reset(NULL); |
142 int real_fd; | 32 int real_fd; |
143 int error = _real_open(path.Join().c_str(), mode, 0666, &real_fd); | 33 int error = _real_open(path.Join().c_str(), mode, 0666, &real_fd); |
144 if (error) | 34 if (error) |
145 return error; | 35 return error; |
146 | 36 |
147 out_node->reset(new PassthroughFsNode(this, real_fd)); | 37 out_node->reset(new RealNode(this, real_fd, true)); |
148 return 0; | 38 return 0; |
149 } | 39 } |
150 | 40 |
151 Error PassthroughFs::OpenResource(const Path& path, ScopedNode* out_node) { | 41 Error PassthroughFs::OpenResource(const Path& path, ScopedNode* out_node) { |
152 int real_fd; | 42 int real_fd; |
153 out_node->reset(NULL); | 43 out_node->reset(NULL); |
154 int error = _real_open_resource(path.Join().c_str(), &real_fd); | 44 int error = _real_open_resource(path.Join().c_str(), &real_fd); |
155 if (error) | 45 if (error) |
156 return error; | 46 return error; |
157 | 47 |
158 out_node->reset(new PassthroughFsNode(this, real_fd)); | 48 out_node->reset(new RealNode(this, real_fd)); |
159 return 0; | 49 return 0; |
160 } | 50 } |
161 | 51 |
162 Error PassthroughFs::Unlink(const Path& path) { | 52 Error PassthroughFs::Unlink(const Path& path) { |
163 // Not implemented by NaCl. | 53 // Not implemented by NaCl. |
164 return ENOSYS; | 54 return ENOSYS; |
165 } | 55 } |
166 | 56 |
167 Error PassthroughFs::Mkdir(const Path& path, int perm) { | 57 Error PassthroughFs::Mkdir(const Path& path, int perm) { |
168 return _real_mkdir(path.Join().c_str(), perm); | 58 return _real_mkdir(path.Join().c_str(), perm); |
169 } | 59 } |
170 | 60 |
171 Error PassthroughFs::Rmdir(const Path& path) { | 61 Error PassthroughFs::Rmdir(const Path& path) { |
172 return _real_rmdir(path.Join().c_str()); | 62 return _real_rmdir(path.Join().c_str()); |
173 } | 63 } |
174 | 64 |
175 Error PassthroughFs::Remove(const Path& path) { | 65 Error PassthroughFs::Remove(const Path& path) { |
176 // Not implemented by NaCl. | 66 // Not implemented by NaCl. |
177 return ENOSYS; | 67 return ENOSYS; |
178 } | 68 } |
179 | 69 |
180 Error PassthroughFs::Rename(const Path& path, const Path& newpath) { | 70 Error PassthroughFs::Rename(const Path& path, const Path& newpath) { |
181 // Not implemented by NaCl. | 71 // Not implemented by NaCl. |
182 return ENOSYS; | 72 return ENOSYS; |
183 } | 73 } |
184 | 74 |
185 } // namespace nacl_io | 75 } // namespace nacl_io |
OLD | NEW |