| OLD | NEW |
| (Empty) |
| 1 /* 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 */ | |
| 5 #if defined(WIN32) | |
| 6 #define _CRT_RAND_S | |
| 7 #endif | |
| 8 | |
| 9 #include <errno.h> | |
| 10 #include <fcntl.h> | |
| 11 #include <string.h> | |
| 12 #include "nacl_mounts/mount_dev.h" | |
| 13 #include "nacl_mounts/mount_node.h" | |
| 14 #include "nacl_mounts/mount_node_dir.h" | |
| 15 #include "nacl_mounts/pepper_interface.h" | |
| 16 #include "utils/auto_lock.h" | |
| 17 | |
| 18 #if defined(__native_client__) | |
| 19 # include <irt.h> | |
| 20 #elif defined(WIN32) | |
| 21 # include <stdlib.h> | |
| 22 #endif | |
| 23 | |
| 24 namespace { | |
| 25 | |
| 26 void ReleaseAndNullNode(MountNode** node) { | |
| 27 if (*node) | |
| 28 (*node)->Release(); | |
| 29 *node = NULL; | |
| 30 } | |
| 31 | |
| 32 class NullNode : public MountNode { | |
| 33 public: | |
| 34 explicit NullNode(Mount* mount); | |
| 35 | |
| 36 virtual int Read(size_t offs, void* buf, size_t count); | |
| 37 virtual int Write(size_t offs, const void* buf, size_t count); | |
| 38 }; | |
| 39 | |
| 40 class ConsoleNode : public NullNode { | |
| 41 public: | |
| 42 ConsoleNode(Mount* mount, PP_LogLevel level); | |
| 43 | |
| 44 virtual int Write(size_t offs, const void* buf, size_t count); | |
| 45 | |
| 46 private: | |
| 47 PP_LogLevel level_; | |
| 48 }; | |
| 49 | |
| 50 | |
| 51 class TtyNode : public NullNode { | |
| 52 public: | |
| 53 explicit TtyNode(Mount* mount); | |
| 54 | |
| 55 virtual int Write(size_t offs, const void* buf, size_t count); | |
| 56 }; | |
| 57 | |
| 58 | |
| 59 class ZeroNode : public MountNode { | |
| 60 public: | |
| 61 explicit ZeroNode(Mount* mount); | |
| 62 | |
| 63 virtual int Read(size_t offs, void* buf, size_t count); | |
| 64 virtual int Write(size_t offs, const void* buf, size_t count); | |
| 65 }; | |
| 66 | |
| 67 class UrandomNode : public MountNode { | |
| 68 public: | |
| 69 explicit UrandomNode(Mount* mount); | |
| 70 | |
| 71 virtual int Read(size_t offs, void* buf, size_t count); | |
| 72 virtual int Write(size_t offs, const void* buf, size_t count); | |
| 73 | |
| 74 private: | |
| 75 #if defined(__native_client__) | |
| 76 nacl_irt_random random_interface_; | |
| 77 bool interface_ok_; | |
| 78 #endif | |
| 79 }; | |
| 80 | |
| 81 NullNode::NullNode(Mount* mount) | |
| 82 : MountNode(mount) { | |
| 83 stat_.st_mode = S_IFCHR; | |
| 84 } | |
| 85 | |
| 86 int NullNode::Read(size_t offs, void* buf, size_t count) { | |
| 87 return 0; | |
| 88 } | |
| 89 | |
| 90 int NullNode::Write(size_t offs, const void* buf, size_t count) { | |
| 91 return count; | |
| 92 } | |
| 93 | |
| 94 ConsoleNode::ConsoleNode(Mount* mount, PP_LogLevel level) | |
| 95 : NullNode(mount), | |
| 96 level_(level) { | |
| 97 stat_.st_mode = S_IFCHR; | |
| 98 } | |
| 99 | |
| 100 int ConsoleNode::Write(size_t offs, const void* buf, size_t count) { | |
| 101 ConsoleInterface* con_intr = mount_->ppapi()->GetConsoleInterface(); | |
| 102 VarInterface* var_intr = mount_->ppapi()->GetVarInterface(); | |
| 103 | |
| 104 if (var_intr && con_intr) { | |
| 105 const char* data = static_cast<const char *>(buf); | |
| 106 uint32_t len = static_cast<uint32_t>(count); | |
| 107 struct PP_Var val = var_intr->VarFromUtf8(data, len); | |
| 108 con_intr->Log(mount_->ppapi()->GetInstance(), level_, val); | |
| 109 return count; | |
| 110 } | |
| 111 return 0; | |
| 112 } | |
| 113 | |
| 114 | |
| 115 TtyNode::TtyNode(Mount* mount) | |
| 116 : NullNode(mount) { | |
| 117 } | |
| 118 | |
| 119 int TtyNode::Write(size_t offs, const void* buf, size_t count) { | |
| 120 MessagingInterface* msg_intr = mount_->ppapi()->GetMessagingInterface(); | |
| 121 VarInterface* var_intr = mount_->ppapi()->GetVarInterface(); | |
| 122 | |
| 123 if (var_intr && msg_intr) { | |
| 124 const char* data = static_cast<const char *>(buf); | |
| 125 uint32_t len = static_cast<uint32_t>(count); | |
| 126 struct PP_Var val = var_intr->VarFromUtf8(data, len); | |
| 127 msg_intr->PostMessage(mount_->ppapi()->GetInstance(), val); | |
| 128 return count; | |
| 129 } | |
| 130 return 0; | |
| 131 } | |
| 132 | |
| 133 | |
| 134 ZeroNode::ZeroNode(Mount* mount) | |
| 135 : MountNode(mount) { | |
| 136 stat_.st_mode = S_IFCHR; | |
| 137 } | |
| 138 | |
| 139 int ZeroNode::Read(size_t offs, void* buf, size_t count) { | |
| 140 memset(buf, 0, count); | |
| 141 return count; | |
| 142 } | |
| 143 | |
| 144 int ZeroNode::Write(size_t offs, const void* buf, size_t count) { | |
| 145 return count; | |
| 146 } | |
| 147 | |
| 148 UrandomNode::UrandomNode(Mount* mount) | |
| 149 : MountNode(mount) { | |
| 150 stat_.st_mode = S_IFCHR; | |
| 151 #if defined(__native_client__) | |
| 152 size_t result = nacl_interface_query(NACL_IRT_RANDOM_v0_1, &random_interface_, | |
| 153 sizeof(random_interface_)); | |
| 154 interface_ok_ = result != 0; | |
| 155 #endif | |
| 156 } | |
| 157 | |
| 158 int UrandomNode::Read(size_t offs, void* buf, size_t count) { | |
| 159 #if defined(__native_client__) | |
| 160 if (interface_ok_) { | |
| 161 size_t nread; | |
| 162 int result = (*random_interface_.get_random_bytes)(buf, count, &nread); | |
| 163 if (result != 0) { | |
| 164 errno = result; | |
| 165 return 0; | |
| 166 } | |
| 167 | |
| 168 return count; | |
| 169 } | |
| 170 | |
| 171 errno = EBADF; | |
| 172 return 0; | |
| 173 #elif defined(WIN32) | |
| 174 char* out = static_cast<char*>(buf); | |
| 175 size_t bytes_left = count; | |
| 176 while (bytes_left) { | |
| 177 unsigned int random_int; | |
| 178 errno_t err = rand_s(&random_int); | |
| 179 if (err) { | |
| 180 errno = err; | |
| 181 return count - bytes_left; | |
| 182 } | |
| 183 | |
| 184 int bytes_to_copy = std::min(bytes_left, sizeof(random_int)); | |
| 185 memcpy(out, &random_int, bytes_to_copy); | |
| 186 out += bytes_to_copy; | |
| 187 bytes_left -= bytes_to_copy; | |
| 188 } | |
| 189 | |
| 190 return count; | |
| 191 #endif | |
| 192 } | |
| 193 | |
| 194 int UrandomNode::Write(size_t offs, const void* buf, size_t count) { | |
| 195 return count; | |
| 196 } | |
| 197 | |
| 198 | |
| 199 | |
| 200 } // namespace | |
| 201 | |
| 202 MountNode *MountDev::Open(const Path& path, int mode) { | |
| 203 AutoLock lock(&lock_); | |
| 204 | |
| 205 // Don't allow creating any files. | |
| 206 if (mode & O_CREAT) | |
| 207 return NULL; | |
| 208 | |
| 209 MountNode* node = root_->FindChild(path.Join()); | |
| 210 if (node) | |
| 211 node->Acquire(); | |
| 212 return node; | |
| 213 } | |
| 214 | |
| 215 int MountDev::Unlink(const Path& path) { | |
| 216 errno = EINVAL; | |
| 217 return -1; | |
| 218 } | |
| 219 | |
| 220 int MountDev::Mkdir(const Path& path, int permissions) { | |
| 221 errno = EINVAL; | |
| 222 return -1; | |
| 223 } | |
| 224 | |
| 225 int MountDev::Rmdir(const Path& path) { | |
| 226 errno = EINVAL; | |
| 227 return -1; | |
| 228 } | |
| 229 | |
| 230 int MountDev::Remove(const Path& path) { | |
| 231 errno = EINVAL; | |
| 232 return -1; | |
| 233 } | |
| 234 | |
| 235 MountDev::MountDev() | |
| 236 : null_node_(NULL), | |
| 237 zero_node_(NULL), | |
| 238 random_node_(NULL), | |
| 239 console0_node_(NULL), | |
| 240 console1_node_(NULL), | |
| 241 console2_node_(NULL), | |
| 242 console3_node_(NULL), | |
| 243 tty_node_(NULL) { | |
| 244 } | |
| 245 | |
| 246 bool MountDev::Init(int dev, StringMap_t& args, PepperInterface* ppapi) { | |
| 247 if (!Mount::Init(dev, args, ppapi)) | |
| 248 return false; | |
| 249 | |
| 250 root_ = new MountNodeDir(this); | |
| 251 null_node_ = new NullNode(this); | |
| 252 root_->AddChild("/null", null_node_); | |
| 253 zero_node_ = new ZeroNode(this); | |
| 254 root_->AddChild("/zero", zero_node_); | |
| 255 random_node_ = new UrandomNode(this); | |
| 256 root_->AddChild("/urandom", random_node_); | |
| 257 | |
| 258 console0_node_ = new ConsoleNode(this, PP_LOGLEVEL_TIP); | |
| 259 root_->AddChild("/console0", console0_node_); | |
| 260 console1_node_ = new ConsoleNode(this, PP_LOGLEVEL_LOG); | |
| 261 root_->AddChild("/console1", console1_node_); | |
| 262 console2_node_ = new ConsoleNode(this, PP_LOGLEVEL_WARNING); | |
| 263 root_->AddChild("/console2", console2_node_); | |
| 264 console3_node_ = new ConsoleNode(this, PP_LOGLEVEL_ERROR); | |
| 265 root_->AddChild("/console3", console3_node_); | |
| 266 | |
| 267 tty_node_ = new TtyNode(this); | |
| 268 root_->AddChild("/tty", tty_node_); | |
| 269 return true; | |
| 270 } | |
| 271 | |
| 272 void MountDev::Destroy() { | |
| 273 ReleaseAndNullNode(&tty_node_); | |
| 274 ReleaseAndNullNode(&console3_node_); | |
| 275 ReleaseAndNullNode(&console2_node_); | |
| 276 ReleaseAndNullNode(&console1_node_); | |
| 277 ReleaseAndNullNode(&console0_node_); | |
| 278 ReleaseAndNullNode(&random_node_); | |
| 279 ReleaseAndNullNode(&zero_node_); | |
| 280 ReleaseAndNullNode(&null_node_); | |
| 281 ReleaseAndNullNode(&root_); | |
| 282 } | |
| OLD | NEW |