Index: native_client_sdk/src/libraries/nacl_io/mount_dev.cc |
diff --git a/native_client_sdk/src/libraries/nacl_io/mount_dev.cc b/native_client_sdk/src/libraries/nacl_io/mount_dev.cc |
index 83d2e55423435c63cec0a5776365d610faa53c43..f13d5e2e014414fc9d7fe5da9ca801cca2e36f62 100644 |
--- a/native_client_sdk/src/libraries/nacl_io/mount_dev.cc |
+++ b/native_client_sdk/src/libraries/nacl_io/mount_dev.cc |
@@ -17,28 +17,23 @@ |
#include "utils/auto_lock.h" |
#if defined(__native_client__) |
-# include <irt.h> |
+#include <irt.h> |
#elif defined(WIN32) |
-# include <stdlib.h> |
+#include <stdlib.h> |
#endif |
- |
namespace { |
-void ReleaseAndNullNode(MountNode** node) { |
- if (*node) |
- (*node)->Release(); |
- *node = NULL; |
-} |
- |
- |
class RealNode : public MountNode { |
public: |
RealNode(Mount* mount, int fd); |
- virtual int Read(size_t offs, void* buf, size_t count); |
- virtual int Write(size_t offs, const void* buf, size_t count); |
- virtual int GetStat(struct stat* stat); |
+ virtual Error Read(size_t offs, void* buf, size_t count, int* out_bytes); |
+ virtual Error Write(size_t offs, |
+ const void* buf, |
+ size_t count, |
+ int* out_bytes); |
+ virtual Error GetStat(struct stat* stat); |
protected: |
int fd_; |
@@ -48,43 +43,56 @@ class NullNode : public MountNode { |
public: |
explicit NullNode(Mount* mount); |
- virtual int Read(size_t offs, void* buf, size_t count); |
- virtual int Write(size_t offs, const void* buf, size_t count); |
+ virtual Error Read(size_t offs, void* buf, size_t count, int* out_bytes); |
+ virtual Error Write(size_t offs, |
+ const void* buf, |
+ size_t count, |
+ int* out_bytes); |
}; |
class ConsoleNode : public NullNode { |
public: |
ConsoleNode(Mount* mount, PP_LogLevel level); |
- virtual int Write(size_t offs, const void* buf, size_t count); |
+ virtual Error Write(size_t offs, |
+ const void* buf, |
+ size_t count, |
+ int* out_bytes); |
-private: |
+ private: |
PP_LogLevel level_; |
}; |
- |
class TtyNode : public NullNode { |
public: |
explicit TtyNode(Mount* mount); |
- virtual int Write(size_t offs, const void* buf, size_t count); |
+ virtual Error Write(size_t offs, |
+ const void* buf, |
+ size_t count, |
+ int* out_bytes); |
}; |
- |
class ZeroNode : public MountNode { |
public: |
explicit ZeroNode(Mount* mount); |
- virtual int Read(size_t offs, void* buf, size_t count); |
- virtual int Write(size_t offs, const void* buf, size_t count); |
+ virtual Error Read(size_t offs, void* buf, size_t count, int* out_bytes); |
+ virtual Error Write(size_t offs, |
+ const void* buf, |
+ size_t count, |
+ int* out_bytes); |
}; |
class UrandomNode : public MountNode { |
public: |
explicit UrandomNode(Mount* mount); |
- virtual int Read(size_t offs, void* buf, size_t count); |
- virtual int Write(size_t offs, const void* buf, size_t count); |
+ virtual Error Read(size_t offs, void* buf, size_t count, int* out_bytes); |
+ virtual Error Write(size_t offs, |
+ const void* buf, |
+ size_t count, |
+ int* out_bytes); |
private: |
#if defined(__native_client__) |
@@ -93,132 +101,141 @@ class UrandomNode : public MountNode { |
#endif |
}; |
-RealNode::RealNode(Mount* mount, int fd) |
- : MountNode(mount), |
- fd_(fd) { |
+RealNode::RealNode(Mount* mount, int fd) : MountNode(mount), fd_(fd) { |
stat_.st_mode = S_IFCHR; |
} |
-int RealNode::Read(size_t offs, void* buf, size_t count) { |
+Error RealNode::Read(size_t offs, void* buf, size_t count, int* out_bytes) { |
+ *out_bytes = 0; |
+ |
size_t readcnt; |
int err = _real_read(fd_, buf, count, &readcnt); |
- if (err) { |
- errno = err; |
- return -1; |
- } |
- return static_cast<int>(readcnt); |
+ if (err) |
+ return err; |
+ |
+ *out_bytes = static_cast<int>(readcnt); |
+ return 0; |
} |
-int RealNode::Write(size_t offs, const void* buf, size_t count) { |
+Error RealNode::Write(size_t offs, |
+ const void* buf, |
+ size_t count, |
+ int* out_bytes) { |
+ *out_bytes = 0; |
+ |
size_t writecnt; |
int err = _real_write(fd_, buf, count, &writecnt); |
- if (err) { |
- errno = err; |
- return -1; |
- } |
- return static_cast<int>(writecnt); |
-} |
+ if (err) |
+ return err; |
-int RealNode::GetStat(struct stat* stat) { |
- int err = _real_fstat(fd_, stat); |
- if (err) { |
- errno = err; |
- return -1; |
- } |
+ *out_bytes = static_cast<int>(writecnt); |
return 0; |
} |
-NullNode::NullNode(Mount* mount) |
- : MountNode(mount) { |
- stat_.st_mode = S_IFCHR; |
-} |
+Error RealNode::GetStat(struct stat* stat) { return _real_fstat(fd_, stat); } |
+ |
+NullNode::NullNode(Mount* mount) : MountNode(mount) { stat_.st_mode = S_IFCHR; } |
-int NullNode::Read(size_t offs, void* buf, size_t count) { |
+Error NullNode::Read(size_t offs, void* buf, size_t count, int* out_bytes) { |
+ *out_bytes = 0; |
return 0; |
} |
-int NullNode::Write(size_t offs, const void* buf, size_t count) { |
- return count; |
+Error NullNode::Write(size_t offs, |
+ const void* buf, |
+ size_t count, |
+ int* out_bytes) { |
+ *out_bytes = count; |
+ return 0; |
} |
ConsoleNode::ConsoleNode(Mount* mount, PP_LogLevel level) |
- : NullNode(mount), |
- level_(level) { |
+ : NullNode(mount), level_(level) { |
stat_.st_mode = S_IFCHR; |
} |
-int ConsoleNode::Write(size_t offs, const void* buf, size_t count) { |
+Error ConsoleNode::Write(size_t offs, |
+ const void* buf, |
+ size_t count, |
+ int* out_bytes) { |
+ *out_bytes = 0; |
+ |
ConsoleInterface* con_intr = mount_->ppapi()->GetConsoleInterface(); |
VarInterface* var_intr = mount_->ppapi()->GetVarInterface(); |
- if (var_intr && con_intr) { |
- const char* data = static_cast<const char *>(buf); |
- uint32_t len = static_cast<uint32_t>(count); |
- struct PP_Var val = var_intr->VarFromUtf8(data, len); |
- con_intr->Log(mount_->ppapi()->GetInstance(), level_, val); |
- return count; |
- } |
+ if (!(var_intr && con_intr)) |
+ return ENOSYS; |
+ |
+ const char* data = static_cast<const char*>(buf); |
+ uint32_t len = static_cast<uint32_t>(count); |
+ struct PP_Var val = var_intr->VarFromUtf8(data, len); |
+ con_intr->Log(mount_->ppapi()->GetInstance(), level_, val); |
+ |
+ *out_bytes = count; |
return 0; |
} |
+TtyNode::TtyNode(Mount* mount) : NullNode(mount) {} |
-TtyNode::TtyNode(Mount* mount) |
- : NullNode(mount) { |
-} |
+Error TtyNode::Write(size_t offs, |
+ const void* buf, |
+ size_t count, |
+ int* out_bytes) { |
+ *out_bytes = 0; |
-int TtyNode::Write(size_t offs, const void* buf, size_t count) { |
MessagingInterface* msg_intr = mount_->ppapi()->GetMessagingInterface(); |
VarInterface* var_intr = mount_->ppapi()->GetVarInterface(); |
- if (var_intr && msg_intr) { |
- const char* data = static_cast<const char *>(buf); |
- uint32_t len = static_cast<uint32_t>(count); |
- struct PP_Var val = var_intr->VarFromUtf8(data, len); |
- msg_intr->PostMessage(mount_->ppapi()->GetInstance(), val); |
- return count; |
- } |
- return 0; |
-} |
+ if (!(var_intr && msg_intr)) |
+ return ENOSYS; |
+ const char* data = static_cast<const char*>(buf); |
+ uint32_t len = static_cast<uint32_t>(count); |
+ struct PP_Var val = var_intr->VarFromUtf8(data, len); |
+ msg_intr->PostMessage(mount_->ppapi()->GetInstance(), val); |
-ZeroNode::ZeroNode(Mount* mount) |
- : MountNode(mount) { |
- stat_.st_mode = S_IFCHR; |
+ *out_bytes = count; |
+ return 0; |
} |
-int ZeroNode::Read(size_t offs, void* buf, size_t count) { |
+ZeroNode::ZeroNode(Mount* mount) : MountNode(mount) { stat_.st_mode = S_IFCHR; } |
+ |
+Error ZeroNode::Read(size_t offs, void* buf, size_t count, int* out_bytes) { |
memset(buf, 0, count); |
- return count; |
+ *out_bytes = count; |
+ return 0; |
} |
-int ZeroNode::Write(size_t offs, const void* buf, size_t count) { |
- return count; |
+Error ZeroNode::Write(size_t offs, |
+ const void* buf, |
+ size_t count, |
+ int* out_bytes) { |
+ *out_bytes = count; |
+ return 0; |
} |
-UrandomNode::UrandomNode(Mount* mount) |
- : MountNode(mount) { |
+UrandomNode::UrandomNode(Mount* mount) : MountNode(mount) { |
stat_.st_mode = S_IFCHR; |
#if defined(__native_client__) |
- size_t result = nacl_interface_query(NACL_IRT_RANDOM_v0_1, &random_interface_, |
- sizeof(random_interface_)); |
+ size_t result = nacl_interface_query( |
+ NACL_IRT_RANDOM_v0_1, &random_interface_, sizeof(random_interface_)); |
interface_ok_ = result != 0; |
#endif |
} |
-int UrandomNode::Read(size_t offs, void* buf, size_t count) { |
+Error UrandomNode::Read(size_t offs, void* buf, size_t count, int* out_bytes) { |
+ *out_bytes = 0; |
+ |
#if defined(__native_client__) |
- if (interface_ok_) { |
- size_t nread; |
- int result = (*random_interface_.get_random_bytes)(buf, count, &nread); |
- if (result != 0) { |
- errno = result; |
- return 0; |
- } |
+ if (!interface_ok_) |
+ return EBADF; |
- return count; |
- } |
+ size_t nread; |
+ int error = (*random_interface_.get_random_bytes)(buf, count, &nread); |
+ if (error) |
+ return error; |
- errno = EBADF; |
+ *out_bytes = count; |
return 0; |
#elif defined(WIN32) |
char* out = static_cast<char*>(buf); |
@@ -227,8 +244,8 @@ int UrandomNode::Read(size_t offs, void* buf, size_t count) { |
unsigned int random_int; |
errno_t err = rand_s(&random_int); |
if (err) { |
- errno = err; |
- return count - bytes_left; |
+ *out_bytes = count - bytes_left; |
+ return err; |
} |
int bytes_to_copy = std::min(bytes_left, sizeof(random_int)); |
@@ -237,107 +254,84 @@ int UrandomNode::Read(size_t offs, void* buf, size_t count) { |
bytes_left -= bytes_to_copy; |
} |
- return count; |
+ *out_bytes = count; |
+ return 0; |
#endif |
} |
-int UrandomNode::Write(size_t offs, const void* buf, size_t count) { |
- return count; |
+Error UrandomNode::Write(size_t offs, |
+ const void* buf, |
+ size_t count, |
+ int* out_bytes) { |
+ *out_bytes = count; |
+ return 0; |
} |
- |
- |
} // namespace |
-MountNode *MountDev::Open(const Path& path, int mode) { |
+Error MountDev::Open(const Path& path, int mode, MountNode** out_node) { |
+ *out_node = NULL; |
+ |
AutoLock lock(&lock_); |
// Don't allow creating any files. |
if (mode & O_CREAT) |
- return NULL; |
+ return EINVAL; |
- MountNode* node = root_->FindChild(path.Join()); |
- if (node) |
- node->Acquire(); |
- return node; |
-} |
+ MountNode* node = NULL; |
+ int error = root_->FindChild(path.Join(), &node); |
+ if (error) |
+ return error; |
-int MountDev::Unlink(const Path& path) { |
- errno = EINVAL; |
- return -1; |
+ node->Acquire(); |
+ *out_node = node; |
+ return 0; |
} |
-int MountDev::Mkdir(const Path& path, int permissions) { |
- errno = EINVAL; |
- return -1; |
-} |
+Error MountDev::Unlink(const Path& path) { return EINVAL; } |
-int MountDev::Rmdir(const Path& path) { |
- errno = EINVAL; |
- return -1; |
-} |
+Error MountDev::Mkdir(const Path& path, int permissions) { return EINVAL; } |
-int MountDev::Remove(const Path& path) { |
- errno = EINVAL; |
- return -1; |
-} |
+Error MountDev::Rmdir(const Path& path) { return EINVAL; } |
-MountDev::MountDev() |
- : null_node_(NULL), |
- zero_node_(NULL), |
- random_node_(NULL), |
- console0_node_(NULL), |
- console1_node_(NULL), |
- console2_node_(NULL), |
- console3_node_(NULL), |
- tty_node_(NULL) { |
-} |
+Error MountDev::Remove(const Path& path) { return EINVAL; } |
+ |
+MountDev::MountDev() {} |
-bool MountDev::Init(int dev, StringMap_t& args, PepperInterface* ppapi) { |
- if (!Mount::Init(dev, args, ppapi)) |
+#define INITIALIZE_DEV_NODE(path, klass) \ |
+ error = root_->AddChild(path, new klass(this)); \ |
+ if (error) \ |
return false; |
+#define INITIALIZE_DEV_NODE_1(path, klass, arg) \ |
+ error = root_->AddChild(path, new klass(this, arg)); \ |
+ if (error) \ |
+ return false; |
+ |
+Error MountDev::Init(int dev, StringMap_t& args, PepperInterface* ppapi) { |
+ Error error = Mount::Init(dev, args, ppapi); |
+ if (error) |
+ return error; |
+ |
root_ = new MountNodeDir(this); |
- null_node_ = new NullNode(this); |
- root_->AddChild("/null", null_node_); |
- zero_node_ = new ZeroNode(this); |
- root_->AddChild("/zero", zero_node_); |
- random_node_ = new UrandomNode(this); |
- root_->AddChild("/urandom", random_node_); |
- |
- console0_node_ = new ConsoleNode(this, PP_LOGLEVEL_TIP); |
- root_->AddChild("/console0", console0_node_); |
- console1_node_ = new ConsoleNode(this, PP_LOGLEVEL_LOG); |
- root_->AddChild("/console1", console1_node_); |
- console2_node_ = new ConsoleNode(this, PP_LOGLEVEL_WARNING); |
- root_->AddChild("/console2", console2_node_); |
- console3_node_ = new ConsoleNode(this, PP_LOGLEVEL_ERROR); |
- root_->AddChild("/console3", console3_node_); |
- |
- tty_node_ = new TtyNode(this); |
- root_->AddChild("/tty", tty_node_); |
- |
- stdin_node_ = new RealNode(this, 0); |
- root_->AddChild("/stdin", stdin_node_); |
- stdout_node_ = new RealNode(this, 1); |
- root_->AddChild("/stdout", stdout_node_); |
- stderr_node_ = new RealNode(this, 2); |
- root_->AddChild("/stderr", stderr_node_); |
- |
- return true; |
+ |
+ INITIALIZE_DEV_NODE("/null", NullNode); |
+ INITIALIZE_DEV_NODE("/zero", ZeroNode); |
+ INITIALIZE_DEV_NODE("/urandom", UrandomNode); |
+ INITIALIZE_DEV_NODE_1("/console0", ConsoleNode, PP_LOGLEVEL_TIP); |
+ INITIALIZE_DEV_NODE_1("/console1", ConsoleNode, PP_LOGLEVEL_LOG); |
+ INITIALIZE_DEV_NODE_1("/console2", ConsoleNode, PP_LOGLEVEL_WARNING); |
+ INITIALIZE_DEV_NODE_1("/console3", ConsoleNode, PP_LOGLEVEL_ERROR); |
+ INITIALIZE_DEV_NODE("/tty", TtyNode); |
+ INITIALIZE_DEV_NODE_1("/stdin", RealNode, 0); |
+ INITIALIZE_DEV_NODE_1("/stdout", RealNode, 1); |
+ INITIALIZE_DEV_NODE_1("/stderr", RealNode, 2); |
+ |
+ return 0; |
noelallen1
2013/06/07 21:48:43
Error
binji
2013/06/07 23:23:11
Done.
|
} |
void MountDev::Destroy() { |
- ReleaseAndNullNode(&stdin_node_); |
- ReleaseAndNullNode(&stdout_node_); |
- ReleaseAndNullNode(&stderr_node_); |
- ReleaseAndNullNode(&tty_node_); |
- ReleaseAndNullNode(&console3_node_); |
- ReleaseAndNullNode(&console2_node_); |
- ReleaseAndNullNode(&console1_node_); |
- ReleaseAndNullNode(&console0_node_); |
- ReleaseAndNullNode(&random_node_); |
- ReleaseAndNullNode(&zero_node_); |
- ReleaseAndNullNode(&null_node_); |
- ReleaseAndNullNode(&root_); |
+ if (root_) |
noelallen1
2013/06/07 21:48:43
This assumes derefing the root will defref the chi
binji
2013/06/07 23:23:11
Done.
|
+ root_->Release(); |
+ root_ = NULL; |
} |