| 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 9190a929548dd804d5da317610fc3b3206928093..11893ea09e8ff985c82bd569b12f5731b1132ac6 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 "sdk_util/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); }
|
|
|
| -int NullNode::Read(size_t offs, void* buf, size_t count) {
|
| +NullNode::NullNode(Mount* mount) : MountNode(mount) { stat_.st_mode = S_IFCHR; }
|
| +
|
| +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; }
|
|
|
| -bool MountDev::Init(int dev, StringMap_t& args, PepperInterface* ppapi) {
|
| - if (!Mount::Init(dev, args, ppapi))
|
| - return false;
|
| +MountDev::MountDev() {}
|
| +
|
| +#define INITIALIZE_DEV_NODE(path, klass) \
|
| + error = root_->AddChild(path, new klass(this)); \
|
| + if (error) \
|
| + return error;
|
| +
|
| +#define INITIALIZE_DEV_NODE_1(path, klass, arg) \
|
| + error = root_->AddChild(path, new klass(this, arg)); \
|
| + if (error) \
|
| + return error;
|
| +
|
| +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;
|
| }
|
|
|
| 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_)
|
| + root_->Release();
|
| + root_ = NULL;
|
| }
|
|
|