This source file includes following definitions.
- Init
- Destroy
- GetEventEmitter
- GetEventStatus
- CanOpen
- FSync
- FTruncate
- GetDents
- GetStat
- Ioctl
- VIoctl
- Read
- Write
- MMap
- Tcflush
- Tcgetattr
- Tcsetattr
- GetLinks
- GetMode
- GetSize
- GetType
- SetType
- IsaDir
- IsaFile
- IsaSock
- Isatty
- AddChild
- RemoveChild
- FindChild
- ChildCount
- Link
- Unlink
#include "nacl_io/node.h"
#include <assert.h>
#include <errno.h>
#include <fcntl.h>
#include <poll.h>
#include <string.h>
#include <sys/stat.h>
#include <algorithm>
#include <string>
#include "nacl_io/filesystem.h"
#include "nacl_io/kernel_handle.h"
#include "nacl_io/kernel_wrap_real.h"
#include "nacl_io/osmman.h"
#include "sdk_util/auto_lock.h"
namespace nacl_io {
static const int USR_ID = 1001;
static const int GRP_ID = 1002;
Node::Node(Filesystem* filesystem) : filesystem_(filesystem) {
memset(&stat_, 0, sizeof(stat_));
stat_.st_gid = GRP_ID;
stat_.st_uid = USR_ID;
stat_.st_mode = S_IRALL | S_IWALL;
if (filesystem_)
filesystem_->OnNodeCreated(this);
else
stat_.st_ino = 1;
}
Node::~Node() {}
Error Node::Init(int open_flags) { return 0; }
void Node::Destroy() {
if (filesystem_) {
filesystem_->OnNodeDestroyed(this);
}
}
EventEmitter* Node::GetEventEmitter() { return NULL; }
uint32_t Node::GetEventStatus() {
if (GetEventEmitter())
return GetEventEmitter()->GetEventStatus();
return POLLIN | POLLOUT;
}
bool Node::CanOpen(int open_flags) {
switch (open_flags & 3) {
case O_RDONLY:
return (stat_.st_mode & S_IRALL) != 0;
case O_WRONLY:
return (stat_.st_mode & S_IWALL) != 0;
case O_RDWR:
return (stat_.st_mode & S_IRALL) != 0 && (stat_.st_mode & S_IWALL) != 0;
}
return false;
}
Error Node::FSync() { return 0; }
Error Node::FTruncate(off_t length) { return EINVAL; }
Error Node::GetDents(size_t offs,
struct dirent* pdir,
size_t count,
int* out_bytes) {
*out_bytes = 0;
return ENOTDIR;
}
Error Node::GetStat(struct stat* pstat) {
AUTO_LOCK(node_lock_);
memcpy(pstat, &stat_, sizeof(stat_));
return 0;
}
Error Node::Ioctl(int request, ...) {
va_list ap;
va_start(ap, request);
Error rtn = VIoctl(request, ap);
va_end(ap);
return rtn;
}
Error Node::VIoctl(int request, va_list args) { return EINVAL; }
Error Node::Read(const HandleAttr& attr,
void* buf,
size_t count,
int* out_bytes) {
*out_bytes = 0;
return EINVAL;
}
Error Node::Write(const HandleAttr& attr,
const void* buf,
size_t count,
int* out_bytes) {
*out_bytes = 0;
return EINVAL;
}
Error Node::MMap(void* addr,
size_t length,
int prot,
int flags,
size_t offset,
void** out_addr) {
*out_addr = NULL;
if (prot & PROT_EXEC)
return EPERM;
void* new_addr = addr;
int mmap_error = _real_mmap(
&new_addr, length, prot | PROT_WRITE, flags | MAP_ANONYMOUS, -1, 0);
if (new_addr == MAP_FAILED) {
_real_munmap(new_addr, length);
return mmap_error;
}
HandleAttr data;
data.offs = offset;
data.flags = 0;
int bytes_read;
Error read_error = Read(data, new_addr, length, &bytes_read);
if (read_error) {
_real_munmap(new_addr, length);
return read_error;
}
*out_addr = new_addr;
return 0;
}
Error Node::Tcflush(int queue_selector) { return EINVAL; }
Error Node::Tcgetattr(struct termios* termios_p) { return EINVAL; }
Error Node::Tcsetattr(int optional_actions, const struct termios* termios_p) {
return EINVAL;
}
int Node::GetLinks() { return stat_.st_nlink; }
int Node::GetMode() { return stat_.st_mode & ~S_IFMT; }
Error Node::GetSize(size_t* out_size) {
*out_size = stat_.st_size;
return 0;
}
int Node::GetType() { return stat_.st_mode & S_IFMT; }
void Node::SetType(int type) {
assert((type & ~S_IFMT) == 0);
stat_.st_mode &= ~S_IFMT;
stat_.st_mode |= type;
}
bool Node::IsaDir() { return (stat_.st_mode & S_IFDIR) != 0; }
bool Node::IsaFile() { return (stat_.st_mode & S_IFREG) != 0; }
bool Node::IsaSock() { return (stat_.st_mode & S_IFSOCK) != 0; }
Error Node::Isatty() {
return ENOTTY;
}
Error Node::AddChild(const std::string& name, const ScopedNode& node) {
return ENOTDIR;
}
Error Node::RemoveChild(const std::string& name) { return ENOTDIR; }
Error Node::FindChild(const std::string& name, ScopedNode* out_node) {
out_node->reset(NULL);
return ENOTDIR;
}
int Node::ChildCount() { return 0; }
void Node::Link() { stat_.st_nlink++; }
void Node::Unlink() { stat_.st_nlink--; }
}