blob: 0116745ab443196676c7646259a503ca241c5e0e [file] [log] [blame]
Ben Murdochca12bfa2013-07-23 11:17:05 +01001// 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
3// found in the LICENSE file.
4
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00005#include "nacl_io/mount_node.h"
6
7#include <errno.h>
8#include <fcntl.h>
Ben Murdoch32409262013-08-07 11:04:47 +01009#include <poll.h>
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000010#include <string.h>
11#include <sys/stat.h>
Ben Murdocheb525c52013-07-10 11:40:50 +010012
13#include <algorithm>
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000014#include <string>
15
16#include "nacl_io/kernel_wrap_real.h"
17#include "nacl_io/mount.h"
18#include "nacl_io/osmman.h"
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +010019#include "sdk_util/auto_lock.h"
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000020
Ben Murdochca12bfa2013-07-23 11:17:05 +010021namespace nacl_io {
22
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000023static const int USR_ID = 1001;
24static const int GRP_ID = 1002;
25
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +010026MountNode::MountNode(Mount* mount) : mount_(mount) {
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000027 memset(&stat_, 0, sizeof(stat_));
28 stat_.st_gid = GRP_ID;
29 stat_.st_uid = USR_ID;
30
31 // Mount should normally never be NULL, but may be null in tests.
Torne (Richard Coles)90dce4d2013-05-29 14:40:03 +010032 // If NULL, at least set the inode to a valid (nonzero) value.
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000033 if (mount_)
34 mount_->OnNodeCreated(this);
Torne (Richard Coles)90dce4d2013-05-29 14:40:03 +010035 else
36 stat_.st_ino = 1;
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000037}
38
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +010039MountNode::~MountNode() {}
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000040
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +010041Error MountNode::Init(int perm) {
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000042 stat_.st_mode |= perm;
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +010043 return 0;
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000044}
45
46void MountNode::Destroy() {
47 if (mount_) {
48 mount_->OnNodeDestroyed(this);
49 }
50}
51
Ben Murdochfb250652013-07-31 11:42:55 +010052// Declared in EventEmitter, default to regular files which always return
Ben Murdoch32409262013-08-07 11:04:47 +010053// a ready of TRUE for read, write, or error.
Ben Murdochfb250652013-07-31 11:42:55 +010054uint32_t MountNode::GetEventStatus() {
Ben Murdoch32409262013-08-07 11:04:47 +010055 uint32_t val = POLLIN | POLLOUT | POLLERR;
56 return val;
Ben Murdochfb250652013-07-31 11:42:55 +010057}
58
59
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +010060Error MountNode::FSync() { return 0; }
61
Ben Murdocheb525c52013-07-10 11:40:50 +010062Error MountNode::FTruncate(off_t length) { return EINVAL; }
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000063
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +010064Error MountNode::GetDents(size_t offs,
65 struct dirent* pdir,
66 size_t count,
67 int* out_bytes) {
68 *out_bytes = 0;
69 return ENOTDIR;
Torne (Richard Coles)90dce4d2013-05-29 14:40:03 +010070}
71
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +010072Error MountNode::GetStat(struct stat* pstat) {
Ben Murdoch7dbb3d52013-07-17 14:55:54 +010073 AUTO_LOCK(node_lock_);
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000074 memcpy(pstat, &stat_, sizeof(stat_));
75 return 0;
76}
77
Ben Murdocheb525c52013-07-10 11:40:50 +010078Error MountNode::Ioctl(int request, char* arg) { return EINVAL; }
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000079
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +010080Error MountNode::Read(size_t offs, void* buf, size_t count, int* out_bytes) {
81 *out_bytes = 0;
82 return EINVAL;
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000083}
84
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +010085Error MountNode::Write(size_t offs,
86 const void* buf,
87 size_t count,
88 int* out_bytes) {
89 *out_bytes = 0;
90 return EINVAL;
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000091}
92
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +010093Error MountNode::MMap(void* addr,
94 size_t length,
95 int prot,
96 int flags,
97 size_t offset,
98 void** out_addr) {
99 *out_addr = NULL;
100
Torne (Richard Coles)b2df76e2013-05-13 16:52:09 +0100101 // Never allow mmap'ing PROT_EXEC. The passthrough node supports this, but we
102 // don't. Fortunately, glibc will fallback if this fails, so dlopen will
103 // continue to work.
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +0100104 if (prot & PROT_EXEC)
105 return EPERM;
Torne (Richard Coles)b2df76e2013-05-13 16:52:09 +0100106
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000107 // This default mmap support is just enough to make dlopen work.
108 // This implementation just reads from the mount into the mmap'd memory area.
109 void* new_addr = addr;
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +0100110 int mmap_error = _real_mmap(
111 &new_addr, length, prot | PROT_WRITE, flags | MAP_ANONYMOUS, -1, 0);
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100112 if (new_addr == MAP_FAILED) {
113 _real_munmap(new_addr, length);
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +0100114 return mmap_error;
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000115 }
116
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +0100117 int bytes_read;
118 Error read_error = Read(offset, new_addr, length, &bytes_read);
119 if (read_error) {
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100120 _real_munmap(new_addr, length);
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +0100121 return read_error;
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000122 }
123
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +0100124 *out_addr = new_addr;
125 return 0;
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000126}
127
Ben Murdochbb1529c2013-08-08 10:24:53 +0100128Error MountNode::Tcflush(int queue_selector) {
129 return EINVAL;
130}
131
132Error MountNode::Tcgetattr(struct termios* termios_p) {
133 return EINVAL;
134}
135
136Error MountNode::Tcsetattr(int optional_actions,
137 const struct termios *termios_p) {
138 return EINVAL;
139}
140
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +0100141int MountNode::GetLinks() { return stat_.st_nlink; }
142
143int MountNode::GetMode() { return stat_.st_mode & ~S_IFMT; }
144
145Error MountNode::GetSize(size_t* out_size) {
146 *out_size = stat_.st_size;
147 return 0;
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000148}
149
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +0100150int MountNode::GetType() { return stat_.st_mode & S_IFMT; }
151
152bool MountNode::IsaDir() { return (stat_.st_mode & S_IFDIR) != 0; }
153
154bool MountNode::IsaFile() { return (stat_.st_mode & S_IFREG) != 0; }
155
156bool MountNode::IsaTTY() { return (stat_.st_mode & S_IFCHR) != 0; }
157
Ben Murdocheb525c52013-07-10 11:40:50 +0100158Error MountNode::AddChild(const std::string& name,
159 const ScopedMountNode& node) {
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +0100160 return ENOTDIR;
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000161}
162
Ben Murdocheb525c52013-07-10 11:40:50 +0100163Error MountNode::RemoveChild(const std::string& name) { return ENOTDIR; }
164
165Error MountNode::FindChild(const std::string& name, ScopedMountNode* out_node) {
166 out_node->reset(NULL);
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +0100167 return ENOTDIR;
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000168}
169
Ben Murdocheb525c52013-07-10 11:40:50 +0100170int MountNode::ChildCount() { return 0; }
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000171
Ben Murdocheb525c52013-07-10 11:40:50 +0100172void MountNode::Link() { stat_.st_nlink++; }
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000173
Ben Murdocheb525c52013-07-10 11:40:50 +0100174void MountNode::Unlink() { stat_.st_nlink--; }
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000175
Ben Murdochca12bfa2013-07-23 11:17:05 +0100176} // namespace nacl_io
177