Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(62)

Side by Side Diff: native_client_sdk/src/libraries/nacl_io/mount_dev.cc

Issue 16232016: [NaCl SDK] nacl_io: big refactor to return error value (errno). (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: merge master, fix windows Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 /* Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 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 #if defined(WIN32) 5 #if defined(WIN32)
6 #define _CRT_RAND_S 6 #define _CRT_RAND_S
7 #endif 7 #endif
8 8
9 #include <errno.h> 9 #include <errno.h>
10 #include <fcntl.h> 10 #include <fcntl.h>
11 #include <string.h> 11 #include <string.h>
12 #include "nacl_io/kernel_wrap_real.h" 12 #include "nacl_io/kernel_wrap_real.h"
13 #include "nacl_io/mount_dev.h" 13 #include "nacl_io/mount_dev.h"
14 #include "nacl_io/mount_node.h" 14 #include "nacl_io/mount_node.h"
15 #include "nacl_io/mount_node_dir.h" 15 #include "nacl_io/mount_node_dir.h"
16 #include "nacl_io/pepper_interface.h" 16 #include "nacl_io/pepper_interface.h"
17 #include "sdk_util/auto_lock.h" 17 #include "sdk_util/auto_lock.h"
18 18
19 #if defined(__native_client__) 19 #if defined(__native_client__)
20 # include <irt.h> 20 #include <irt.h>
21 #elif defined(WIN32) 21 #elif defined(WIN32)
22 # include <stdlib.h> 22 #include <stdlib.h>
23 #endif 23 #endif
24 24
25
26 namespace { 25 namespace {
27 26
28 void ReleaseAndNullNode(MountNode** node) {
29 if (*node)
30 (*node)->Release();
31 *node = NULL;
32 }
33
34
35 class RealNode : public MountNode { 27 class RealNode : public MountNode {
36 public: 28 public:
37 RealNode(Mount* mount, int fd); 29 RealNode(Mount* mount, int fd);
38 30
39 virtual int Read(size_t offs, void* buf, size_t count); 31 virtual Error Read(size_t offs, void* buf, size_t count, int* out_bytes);
40 virtual int Write(size_t offs, const void* buf, size_t count); 32 virtual Error Write(size_t offs,
41 virtual int GetStat(struct stat* stat); 33 const void* buf,
34 size_t count,
35 int* out_bytes);
36 virtual Error GetStat(struct stat* stat);
42 37
43 protected: 38 protected:
44 int fd_; 39 int fd_;
45 }; 40 };
46 41
47 class NullNode : public MountNode { 42 class NullNode : public MountNode {
48 public: 43 public:
49 explicit NullNode(Mount* mount); 44 explicit NullNode(Mount* mount);
50 45
51 virtual int Read(size_t offs, void* buf, size_t count); 46 virtual Error Read(size_t offs, void* buf, size_t count, int* out_bytes);
52 virtual int Write(size_t offs, const void* buf, size_t count); 47 virtual Error Write(size_t offs,
48 const void* buf,
49 size_t count,
50 int* out_bytes);
53 }; 51 };
54 52
55 class ConsoleNode : public NullNode { 53 class ConsoleNode : public NullNode {
56 public: 54 public:
57 ConsoleNode(Mount* mount, PP_LogLevel level); 55 ConsoleNode(Mount* mount, PP_LogLevel level);
58 56
59 virtual int Write(size_t offs, const void* buf, size_t count); 57 virtual Error Write(size_t offs,
58 const void* buf,
59 size_t count,
60 int* out_bytes);
60 61
61 private: 62 private:
62 PP_LogLevel level_; 63 PP_LogLevel level_;
63 }; 64 };
64 65
65
66 class TtyNode : public NullNode { 66 class TtyNode : public NullNode {
67 public: 67 public:
68 explicit TtyNode(Mount* mount); 68 explicit TtyNode(Mount* mount);
69 69
70 virtual int Write(size_t offs, const void* buf, size_t count); 70 virtual Error Write(size_t offs,
71 const void* buf,
72 size_t count,
73 int* out_bytes);
71 }; 74 };
72 75
73
74 class ZeroNode : public MountNode { 76 class ZeroNode : public MountNode {
75 public: 77 public:
76 explicit ZeroNode(Mount* mount); 78 explicit ZeroNode(Mount* mount);
77 79
78 virtual int Read(size_t offs, void* buf, size_t count); 80 virtual Error Read(size_t offs, void* buf, size_t count, int* out_bytes);
79 virtual int Write(size_t offs, const void* buf, size_t count); 81 virtual Error Write(size_t offs,
82 const void* buf,
83 size_t count,
84 int* out_bytes);
80 }; 85 };
81 86
82 class UrandomNode : public MountNode { 87 class UrandomNode : public MountNode {
83 public: 88 public:
84 explicit UrandomNode(Mount* mount); 89 explicit UrandomNode(Mount* mount);
85 90
86 virtual int Read(size_t offs, void* buf, size_t count); 91 virtual Error Read(size_t offs, void* buf, size_t count, int* out_bytes);
87 virtual int Write(size_t offs, const void* buf, size_t count); 92 virtual Error Write(size_t offs,
93 const void* buf,
94 size_t count,
95 int* out_bytes);
88 96
89 private: 97 private:
90 #if defined(__native_client__) 98 #if defined(__native_client__)
91 nacl_irt_random random_interface_; 99 nacl_irt_random random_interface_;
92 bool interface_ok_; 100 bool interface_ok_;
93 #endif 101 #endif
94 }; 102 };
95 103
96 RealNode::RealNode(Mount* mount, int fd) 104 RealNode::RealNode(Mount* mount, int fd) : MountNode(mount), fd_(fd) {
97 : MountNode(mount),
98 fd_(fd) {
99 stat_.st_mode = S_IFCHR; 105 stat_.st_mode = S_IFCHR;
100 } 106 }
101 107
102 int RealNode::Read(size_t offs, void* buf, size_t count) { 108 Error RealNode::Read(size_t offs, void* buf, size_t count, int* out_bytes) {
109 *out_bytes = 0;
110
103 size_t readcnt; 111 size_t readcnt;
104 int err = _real_read(fd_, buf, count, &readcnt); 112 int err = _real_read(fd_, buf, count, &readcnt);
105 if (err) { 113 if (err)
106 errno = err; 114 return err;
107 return -1;
108 }
109 return static_cast<int>(readcnt);
110 }
111 115
112 int RealNode::Write(size_t offs, const void* buf, size_t count) { 116 *out_bytes = static_cast<int>(readcnt);
113 size_t writecnt;
114 int err = _real_write(fd_, buf, count, &writecnt);
115 if (err) {
116 errno = err;
117 return -1;
118 }
119 return static_cast<int>(writecnt);
120 }
121
122 int RealNode::GetStat(struct stat* stat) {
123 int err = _real_fstat(fd_, stat);
124 if (err) {
125 errno = err;
126 return -1;
127 }
128 return 0; 117 return 0;
129 } 118 }
130 119
131 NullNode::NullNode(Mount* mount) 120 Error RealNode::Write(size_t offs,
132 : MountNode(mount) { 121 const void* buf,
122 size_t count,
123 int* out_bytes) {
124 *out_bytes = 0;
125
126 size_t writecnt;
127 int err = _real_write(fd_, buf, count, &writecnt);
128 if (err)
129 return err;
130
131 *out_bytes = static_cast<int>(writecnt);
132 return 0;
133 }
134
135 Error RealNode::GetStat(struct stat* stat) { return _real_fstat(fd_, stat); }
136
137 NullNode::NullNode(Mount* mount) : MountNode(mount) { stat_.st_mode = S_IFCHR; }
138
139 Error NullNode::Read(size_t offs, void* buf, size_t count, int* out_bytes) {
140 *out_bytes = 0;
141 return 0;
142 }
143
144 Error NullNode::Write(size_t offs,
145 const void* buf,
146 size_t count,
147 int* out_bytes) {
148 *out_bytes = count;
149 return 0;
150 }
151
152 ConsoleNode::ConsoleNode(Mount* mount, PP_LogLevel level)
153 : NullNode(mount), level_(level) {
133 stat_.st_mode = S_IFCHR; 154 stat_.st_mode = S_IFCHR;
134 } 155 }
135 156
136 int NullNode::Read(size_t offs, void* buf, size_t count) { 157 Error ConsoleNode::Write(size_t offs,
158 const void* buf,
159 size_t count,
160 int* out_bytes) {
161 *out_bytes = 0;
162
163 ConsoleInterface* con_intr = mount_->ppapi()->GetConsoleInterface();
164 VarInterface* var_intr = mount_->ppapi()->GetVarInterface();
165
166 if (!(var_intr && con_intr))
167 return ENOSYS;
168
169 const char* data = static_cast<const char*>(buf);
170 uint32_t len = static_cast<uint32_t>(count);
171 struct PP_Var val = var_intr->VarFromUtf8(data, len);
172 con_intr->Log(mount_->ppapi()->GetInstance(), level_, val);
173
174 *out_bytes = count;
137 return 0; 175 return 0;
138 } 176 }
139 177
140 int NullNode::Write(size_t offs, const void* buf, size_t count) { 178 TtyNode::TtyNode(Mount* mount) : NullNode(mount) {}
141 return count;
142 }
143 179
144 ConsoleNode::ConsoleNode(Mount* mount, PP_LogLevel level) 180 Error TtyNode::Write(size_t offs,
145 : NullNode(mount), 181 const void* buf,
146 level_(level) { 182 size_t count,
147 stat_.st_mode = S_IFCHR; 183 int* out_bytes) {
148 } 184 *out_bytes = 0;
149 185
150 int ConsoleNode::Write(size_t offs, const void* buf, size_t count) { 186 MessagingInterface* msg_intr = mount_->ppapi()->GetMessagingInterface();
151 ConsoleInterface* con_intr = mount_->ppapi()->GetConsoleInterface();
152 VarInterface* var_intr = mount_->ppapi()->GetVarInterface(); 187 VarInterface* var_intr = mount_->ppapi()->GetVarInterface();
153 188
154 if (var_intr && con_intr) { 189 if (!(var_intr && msg_intr))
155 const char* data = static_cast<const char *>(buf); 190 return ENOSYS;
156 uint32_t len = static_cast<uint32_t>(count); 191
157 struct PP_Var val = var_intr->VarFromUtf8(data, len); 192 const char* data = static_cast<const char*>(buf);
158 con_intr->Log(mount_->ppapi()->GetInstance(), level_, val); 193 uint32_t len = static_cast<uint32_t>(count);
159 return count; 194 struct PP_Var val = var_intr->VarFromUtf8(data, len);
160 } 195 msg_intr->PostMessage(mount_->ppapi()->GetInstance(), val);
196
197 *out_bytes = count;
161 return 0; 198 return 0;
162 } 199 }
163 200
201 ZeroNode::ZeroNode(Mount* mount) : MountNode(mount) { stat_.st_mode = S_IFCHR; }
164 202
165 TtyNode::TtyNode(Mount* mount) 203 Error ZeroNode::Read(size_t offs, void* buf, size_t count, int* out_bytes) {
166 : NullNode(mount) { 204 memset(buf, 0, count);
167 } 205 *out_bytes = count;
168
169 int TtyNode::Write(size_t offs, const void* buf, size_t count) {
170 MessagingInterface* msg_intr = mount_->ppapi()->GetMessagingInterface();
171 VarInterface* var_intr = mount_->ppapi()->GetVarInterface();
172
173 if (var_intr && msg_intr) {
174 const char* data = static_cast<const char *>(buf);
175 uint32_t len = static_cast<uint32_t>(count);
176 struct PP_Var val = var_intr->VarFromUtf8(data, len);
177 msg_intr->PostMessage(mount_->ppapi()->GetInstance(), val);
178 return count;
179 }
180 return 0; 206 return 0;
181 } 207 }
182 208
183 209 Error ZeroNode::Write(size_t offs,
184 ZeroNode::ZeroNode(Mount* mount) 210 const void* buf,
185 : MountNode(mount) { 211 size_t count,
186 stat_.st_mode = S_IFCHR; 212 int* out_bytes) {
213 *out_bytes = count;
214 return 0;
187 } 215 }
188 216
189 int ZeroNode::Read(size_t offs, void* buf, size_t count) { 217 UrandomNode::UrandomNode(Mount* mount) : MountNode(mount) {
190 memset(buf, 0, count);
191 return count;
192 }
193
194 int ZeroNode::Write(size_t offs, const void* buf, size_t count) {
195 return count;
196 }
197
198 UrandomNode::UrandomNode(Mount* mount)
199 : MountNode(mount) {
200 stat_.st_mode = S_IFCHR; 218 stat_.st_mode = S_IFCHR;
201 #if defined(__native_client__) 219 #if defined(__native_client__)
202 size_t result = nacl_interface_query(NACL_IRT_RANDOM_v0_1, &random_interface_, 220 size_t result = nacl_interface_query(
203 sizeof(random_interface_)); 221 NACL_IRT_RANDOM_v0_1, &random_interface_, sizeof(random_interface_));
204 interface_ok_ = result != 0; 222 interface_ok_ = result != 0;
205 #endif 223 #endif
206 } 224 }
207 225
208 int UrandomNode::Read(size_t offs, void* buf, size_t count) { 226 Error UrandomNode::Read(size_t offs, void* buf, size_t count, int* out_bytes) {
227 *out_bytes = 0;
228
209 #if defined(__native_client__) 229 #if defined(__native_client__)
210 if (interface_ok_) { 230 if (!interface_ok_)
211 size_t nread; 231 return EBADF;
212 int result = (*random_interface_.get_random_bytes)(buf, count, &nread);
213 if (result != 0) {
214 errno = result;
215 return 0;
216 }
217 232
218 return count; 233 size_t nread;
219 } 234 int error = (*random_interface_.get_random_bytes)(buf, count, &nread);
235 if (error)
236 return error;
220 237
221 errno = EBADF; 238 *out_bytes = count;
222 return 0; 239 return 0;
223 #elif defined(WIN32) 240 #elif defined(WIN32)
224 char* out = static_cast<char*>(buf); 241 char* out = static_cast<char*>(buf);
225 size_t bytes_left = count; 242 size_t bytes_left = count;
226 while (bytes_left) { 243 while (bytes_left) {
227 unsigned int random_int; 244 unsigned int random_int;
228 errno_t err = rand_s(&random_int); 245 errno_t err = rand_s(&random_int);
229 if (err) { 246 if (err) {
230 errno = err; 247 *out_bytes = count - bytes_left;
231 return count - bytes_left; 248 return err;
232 } 249 }
233 250
234 int bytes_to_copy = std::min(bytes_left, sizeof(random_int)); 251 int bytes_to_copy = std::min(bytes_left, sizeof(random_int));
235 memcpy(out, &random_int, bytes_to_copy); 252 memcpy(out, &random_int, bytes_to_copy);
236 out += bytes_to_copy; 253 out += bytes_to_copy;
237 bytes_left -= bytes_to_copy; 254 bytes_left -= bytes_to_copy;
238 } 255 }
239 256
240 return count; 257 *out_bytes = count;
258 return 0;
241 #endif 259 #endif
242 } 260 }
243 261
244 int UrandomNode::Write(size_t offs, const void* buf, size_t count) { 262 Error UrandomNode::Write(size_t offs,
245 return count; 263 const void* buf,
264 size_t count,
265 int* out_bytes) {
266 *out_bytes = count;
267 return 0;
246 } 268 }
247 269
248
249
250 } // namespace 270 } // namespace
251 271
252 MountNode *MountDev::Open(const Path& path, int mode) { 272 Error MountDev::Open(const Path& path, int mode, MountNode** out_node) {
273 *out_node = NULL;
274
253 AutoLock lock(&lock_); 275 AutoLock lock(&lock_);
254 276
255 // Don't allow creating any files. 277 // Don't allow creating any files.
256 if (mode & O_CREAT) 278 if (mode & O_CREAT)
257 return NULL; 279 return EINVAL;
258 280
259 MountNode* node = root_->FindChild(path.Join()); 281 MountNode* node = NULL;
260 if (node) 282 int error = root_->FindChild(path.Join(), &node);
261 node->Acquire(); 283 if (error)
262 return node; 284 return error;
285
286 node->Acquire();
287 *out_node = node;
288 return 0;
263 } 289 }
264 290
265 int MountDev::Unlink(const Path& path) { 291 Error MountDev::Unlink(const Path& path) { return EINVAL; }
266 errno = EINVAL;
267 return -1;
268 }
269 292
270 int MountDev::Mkdir(const Path& path, int permissions) { 293 Error MountDev::Mkdir(const Path& path, int permissions) { return EINVAL; }
271 errno = EINVAL;
272 return -1;
273 }
274 294
275 int MountDev::Rmdir(const Path& path) { 295 Error MountDev::Rmdir(const Path& path) { return EINVAL; }
276 errno = EINVAL;
277 return -1;
278 }
279 296
280 int MountDev::Remove(const Path& path) { 297 Error MountDev::Remove(const Path& path) { return EINVAL; }
281 errno = EINVAL;
282 return -1;
283 }
284 298
285 MountDev::MountDev() 299 MountDev::MountDev() {}
286 : null_node_(NULL),
287 zero_node_(NULL),
288 random_node_(NULL),
289 console0_node_(NULL),
290 console1_node_(NULL),
291 console2_node_(NULL),
292 console3_node_(NULL),
293 tty_node_(NULL) {
294 }
295 300
296 bool MountDev::Init(int dev, StringMap_t& args, PepperInterface* ppapi) { 301 #define INITIALIZE_DEV_NODE(path, klass) \
297 if (!Mount::Init(dev, args, ppapi)) 302 error = root_->AddChild(path, new klass(this)); \
298 return false; 303 if (error) \
304 return error;
305
306 #define INITIALIZE_DEV_NODE_1(path, klass, arg) \
307 error = root_->AddChild(path, new klass(this, arg)); \
308 if (error) \
309 return error;
310
311 Error MountDev::Init(int dev, StringMap_t& args, PepperInterface* ppapi) {
312 Error error = Mount::Init(dev, args, ppapi);
313 if (error)
314 return error;
299 315
300 root_ = new MountNodeDir(this); 316 root_ = new MountNodeDir(this);
301 null_node_ = new NullNode(this);
302 root_->AddChild("/null", null_node_);
303 zero_node_ = new ZeroNode(this);
304 root_->AddChild("/zero", zero_node_);
305 random_node_ = new UrandomNode(this);
306 root_->AddChild("/urandom", random_node_);
307 317
308 console0_node_ = new ConsoleNode(this, PP_LOGLEVEL_TIP); 318 INITIALIZE_DEV_NODE("/null", NullNode);
309 root_->AddChild("/console0", console0_node_); 319 INITIALIZE_DEV_NODE("/zero", ZeroNode);
310 console1_node_ = new ConsoleNode(this, PP_LOGLEVEL_LOG); 320 INITIALIZE_DEV_NODE("/urandom", UrandomNode);
311 root_->AddChild("/console1", console1_node_); 321 INITIALIZE_DEV_NODE_1("/console0", ConsoleNode, PP_LOGLEVEL_TIP);
312 console2_node_ = new ConsoleNode(this, PP_LOGLEVEL_WARNING); 322 INITIALIZE_DEV_NODE_1("/console1", ConsoleNode, PP_LOGLEVEL_LOG);
313 root_->AddChild("/console2", console2_node_); 323 INITIALIZE_DEV_NODE_1("/console2", ConsoleNode, PP_LOGLEVEL_WARNING);
314 console3_node_ = new ConsoleNode(this, PP_LOGLEVEL_ERROR); 324 INITIALIZE_DEV_NODE_1("/console3", ConsoleNode, PP_LOGLEVEL_ERROR);
315 root_->AddChild("/console3", console3_node_); 325 INITIALIZE_DEV_NODE("/tty", TtyNode);
326 INITIALIZE_DEV_NODE_1("/stdin", RealNode, 0);
327 INITIALIZE_DEV_NODE_1("/stdout", RealNode, 1);
328 INITIALIZE_DEV_NODE_1("/stderr", RealNode, 2);
316 329
317 tty_node_ = new TtyNode(this); 330 return 0;
318 root_->AddChild("/tty", tty_node_);
319
320 stdin_node_ = new RealNode(this, 0);
321 root_->AddChild("/stdin", stdin_node_);
322 stdout_node_ = new RealNode(this, 1);
323 root_->AddChild("/stdout", stdout_node_);
324 stderr_node_ = new RealNode(this, 2);
325 root_->AddChild("/stderr", stderr_node_);
326
327 return true;
328 } 331 }
329 332
330 void MountDev::Destroy() { 333 void MountDev::Destroy() {
331 ReleaseAndNullNode(&stdin_node_); 334 if (root_)
332 ReleaseAndNullNode(&stdout_node_); 335 root_->Release();
333 ReleaseAndNullNode(&stderr_node_); 336 root_ = NULL;
334 ReleaseAndNullNode(&tty_node_);
335 ReleaseAndNullNode(&console3_node_);
336 ReleaseAndNullNode(&console2_node_);
337 ReleaseAndNullNode(&console1_node_);
338 ReleaseAndNullNode(&console0_node_);
339 ReleaseAndNullNode(&random_node_);
340 ReleaseAndNullNode(&zero_node_);
341 ReleaseAndNullNode(&null_node_);
342 ReleaseAndNullNode(&root_);
343 } 337 }
OLDNEW
« no previous file with comments | « native_client_sdk/src/libraries/nacl_io/mount_dev.h ('k') | native_client_sdk/src/libraries/nacl_io/mount_html5fs.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698