Chromium Code Reviews| 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; |
| } |