Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 * Use of this source code is governed by a BSD-style license that can be |
| 3 * found in the LICENSE file. | 3 * found in the LICENSE file. |
| 4 */ | 4 */ |
| 5 #if defined(WIN32) | 5 #if defined(WIN32) |
| 6 #define _CRT_RAND_S | 6 #define _CRT_RAND_S |
| 7 #endif | 7 #endif |
| 8 | 8 |
| 9 #include <errno.h> | 9 #include <errno.h> |
| 10 #include <fcntl.h> | 10 #include <fcntl.h> |
| 11 #include <string.h> | 11 #include <string.h> |
| 12 #include "nacl_io/kernel_wrap_real.h" | 12 #include "nacl_io/kernel_wrap_real.h" |
| 13 #include "nacl_io/mount_dev.h" | 13 #include "nacl_io/mount_dev.h" |
| 14 #include "nacl_io/mount_node.h" | 14 #include "nacl_io/mount_node.h" |
| 15 #include "nacl_io/mount_node_dir.h" | 15 #include "nacl_io/mount_node_dir.h" |
| 16 #include "nacl_io/pepper_interface.h" | 16 #include "nacl_io/pepper_interface.h" |
| 17 #include "utils/auto_lock.h" | 17 #include "utils/auto_lock.h" |
| 18 | 18 |
| 19 #if defined(__native_client__) | 19 #if defined(__native_client__) |
| 20 # include <irt.h> | 20 #include <irt.h> |
| 21 #elif defined(WIN32) | 21 #elif defined(WIN32) |
| 22 # include <stdlib.h> | 22 #include <stdlib.h> |
| 23 #endif | 23 #endif |
| 24 | 24 |
| 25 | |
| 26 namespace { | 25 namespace { |
| 27 | 26 |
| 28 void ReleaseAndNullNode(MountNode** node) { | |
| 29 if (*node) | |
| 30 (*node)->Release(); | |
| 31 *node = NULL; | |
| 32 } | |
| 33 | |
| 34 | |
| 35 class RealNode : public MountNode { | 27 class RealNode : public MountNode { |
| 36 public: | 28 public: |
| 37 RealNode(Mount* mount, int fd); | 29 RealNode(Mount* mount, int fd); |
| 38 | 30 |
| 39 virtual int Read(size_t offs, void* buf, size_t count); | 31 virtual Error Read(size_t offs, void* buf, size_t count, int* out_bytes); |
| 40 virtual int Write(size_t offs, const void* buf, size_t count); | 32 virtual Error Write(size_t offs, |
| 41 virtual int GetStat(struct stat* stat); | 33 const void* buf, |
| 34 size_t count, | |
| 35 int* out_bytes); | |
| 36 virtual Error GetStat(struct stat* stat); | |
| 42 | 37 |
| 43 protected: | 38 protected: |
| 44 int fd_; | 39 int fd_; |
| 45 }; | 40 }; |
| 46 | 41 |
| 47 class NullNode : public MountNode { | 42 class NullNode : public MountNode { |
| 48 public: | 43 public: |
| 49 explicit NullNode(Mount* mount); | 44 explicit NullNode(Mount* mount); |
| 50 | 45 |
| 51 virtual int Read(size_t offs, void* buf, size_t count); | 46 virtual Error Read(size_t offs, void* buf, size_t count, int* out_bytes); |
| 52 virtual int Write(size_t offs, const void* buf, size_t count); | 47 virtual Error Write(size_t offs, |
| 48 const void* buf, | |
| 49 size_t count, | |
| 50 int* out_bytes); | |
| 53 }; | 51 }; |
| 54 | 52 |
| 55 class ConsoleNode : public NullNode { | 53 class ConsoleNode : public NullNode { |
| 56 public: | 54 public: |
| 57 ConsoleNode(Mount* mount, PP_LogLevel level); | 55 ConsoleNode(Mount* mount, PP_LogLevel level); |
| 58 | 56 |
| 59 virtual int Write(size_t offs, const void* buf, size_t count); | 57 virtual Error Write(size_t offs, |
| 58 const void* buf, | |
| 59 size_t count, | |
| 60 int* out_bytes); | |
| 60 | 61 |
| 61 private: | 62 private: |
| 62 PP_LogLevel level_; | 63 PP_LogLevel level_; |
| 63 }; | 64 }; |
| 64 | 65 |
| 65 | |
| 66 class TtyNode : public NullNode { | 66 class TtyNode : public NullNode { |
| 67 public: | 67 public: |
| 68 explicit TtyNode(Mount* mount); | 68 explicit TtyNode(Mount* mount); |
| 69 | 69 |
| 70 virtual int Write(size_t offs, const void* buf, size_t count); | 70 virtual Error Write(size_t offs, |
| 71 const void* buf, | |
| 72 size_t count, | |
| 73 int* out_bytes); | |
| 71 }; | 74 }; |
| 72 | 75 |
| 73 | |
| 74 class ZeroNode : public MountNode { | 76 class ZeroNode : public MountNode { |
| 75 public: | 77 public: |
| 76 explicit ZeroNode(Mount* mount); | 78 explicit ZeroNode(Mount* mount); |
| 77 | 79 |
| 78 virtual int Read(size_t offs, void* buf, size_t count); | 80 virtual Error Read(size_t offs, void* buf, size_t count, int* out_bytes); |
| 79 virtual int Write(size_t offs, const void* buf, size_t count); | 81 virtual Error Write(size_t offs, |
| 82 const void* buf, | |
| 83 size_t count, | |
| 84 int* out_bytes); | |
| 80 }; | 85 }; |
| 81 | 86 |
| 82 class UrandomNode : public MountNode { | 87 class UrandomNode : public MountNode { |
| 83 public: | 88 public: |
| 84 explicit UrandomNode(Mount* mount); | 89 explicit UrandomNode(Mount* mount); |
| 85 | 90 |
| 86 virtual int Read(size_t offs, void* buf, size_t count); | 91 virtual Error Read(size_t offs, void* buf, size_t count, int* out_bytes); |
| 87 virtual int Write(size_t offs, const void* buf, size_t count); | 92 virtual Error Write(size_t offs, |
| 93 const void* buf, | |
| 94 size_t count, | |
| 95 int* out_bytes); | |
| 88 | 96 |
| 89 private: | 97 private: |
| 90 #if defined(__native_client__) | 98 #if defined(__native_client__) |
| 91 nacl_irt_random random_interface_; | 99 nacl_irt_random random_interface_; |
| 92 bool interface_ok_; | 100 bool interface_ok_; |
| 93 #endif | 101 #endif |
| 94 }; | 102 }; |
| 95 | 103 |
| 96 RealNode::RealNode(Mount* mount, int fd) | 104 RealNode::RealNode(Mount* mount, int fd) : MountNode(mount), fd_(fd) { |
| 97 : MountNode(mount), | |
| 98 fd_(fd) { | |
| 99 stat_.st_mode = S_IFCHR; | 105 stat_.st_mode = S_IFCHR; |
| 100 } | 106 } |
| 101 | 107 |
| 102 int RealNode::Read(size_t offs, void* buf, size_t count) { | 108 Error RealNode::Read(size_t offs, void* buf, size_t count, int* out_bytes) { |
| 109 *out_bytes = 0; | |
| 110 | |
| 103 size_t readcnt; | 111 size_t readcnt; |
| 104 int err = _real_read(fd_, buf, count, &readcnt); | 112 int err = _real_read(fd_, buf, count, &readcnt); |
| 105 if (err) { | 113 if (err) |
| 106 errno = err; | 114 return err; |
| 107 return -1; | |
| 108 } | |
| 109 return static_cast<int>(readcnt); | |
| 110 } | |
| 111 | 115 |
| 112 int RealNode::Write(size_t offs, const void* buf, size_t count) { | 116 *out_bytes = static_cast<int>(readcnt); |
| 113 size_t writecnt; | |
| 114 int err = _real_write(fd_, buf, count, &writecnt); | |
| 115 if (err) { | |
| 116 errno = err; | |
| 117 return -1; | |
| 118 } | |
| 119 return static_cast<int>(writecnt); | |
| 120 } | |
| 121 | |
| 122 int RealNode::GetStat(struct stat* stat) { | |
| 123 int err = _real_fstat(fd_, stat); | |
| 124 if (err) { | |
| 125 errno = err; | |
| 126 return -1; | |
| 127 } | |
| 128 return 0; | 117 return 0; |
| 129 } | 118 } |
| 130 | 119 |
| 131 NullNode::NullNode(Mount* mount) | 120 Error RealNode::Write(size_t offs, |
| 132 : MountNode(mount) { | 121 const void* buf, |
| 122 size_t count, | |
| 123 int* out_bytes) { | |
| 124 *out_bytes = 0; | |
| 125 | |
| 126 size_t writecnt; | |
| 127 int err = _real_write(fd_, buf, count, &writecnt); | |
| 128 if (err) | |
| 129 return err; | |
| 130 | |
| 131 *out_bytes = static_cast<int>(writecnt); | |
| 132 return 0; | |
| 133 } | |
| 134 | |
| 135 Error RealNode::GetStat(struct stat* stat) { return _real_fstat(fd_, stat); } | |
| 136 | |
| 137 NullNode::NullNode(Mount* mount) : MountNode(mount) { stat_.st_mode = S_IFCHR; } | |
| 138 | |
| 139 Error NullNode::Read(size_t offs, void* buf, size_t count, int* out_bytes) { | |
| 140 *out_bytes = 0; | |
| 141 return 0; | |
| 142 } | |
| 143 | |
| 144 Error NullNode::Write(size_t offs, | |
| 145 const void* buf, | |
| 146 size_t count, | |
| 147 int* out_bytes) { | |
| 148 *out_bytes = count; | |
| 149 return 0; | |
| 150 } | |
| 151 | |
| 152 ConsoleNode::ConsoleNode(Mount* mount, PP_LogLevel level) | |
| 153 : NullNode(mount), level_(level) { | |
| 133 stat_.st_mode = S_IFCHR; | 154 stat_.st_mode = S_IFCHR; |
| 134 } | 155 } |
| 135 | 156 |
| 136 int NullNode::Read(size_t offs, void* buf, size_t count) { | 157 Error ConsoleNode::Write(size_t offs, |
| 158 const void* buf, | |
| 159 size_t count, | |
| 160 int* out_bytes) { | |
| 161 *out_bytes = 0; | |
| 162 | |
| 163 ConsoleInterface* con_intr = mount_->ppapi()->GetConsoleInterface(); | |
| 164 VarInterface* var_intr = mount_->ppapi()->GetVarInterface(); | |
| 165 | |
| 166 if (!(var_intr && con_intr)) | |
| 167 return ENOSYS; | |
| 168 | |
| 169 const char* data = static_cast<const char*>(buf); | |
| 170 uint32_t len = static_cast<uint32_t>(count); | |
| 171 struct PP_Var val = var_intr->VarFromUtf8(data, len); | |
| 172 con_intr->Log(mount_->ppapi()->GetInstance(), level_, val); | |
| 173 | |
| 174 *out_bytes = count; | |
| 137 return 0; | 175 return 0; |
| 138 } | 176 } |
| 139 | 177 |
| 140 int NullNode::Write(size_t offs, const void* buf, size_t count) { | 178 TtyNode::TtyNode(Mount* mount) : NullNode(mount) {} |
| 141 return count; | |
| 142 } | |
| 143 | 179 |
| 144 ConsoleNode::ConsoleNode(Mount* mount, PP_LogLevel level) | 180 Error TtyNode::Write(size_t offs, |
| 145 : NullNode(mount), | 181 const void* buf, |
| 146 level_(level) { | 182 size_t count, |
| 147 stat_.st_mode = S_IFCHR; | 183 int* out_bytes) { |
| 148 } | 184 *out_bytes = 0; |
| 149 | 185 |
| 150 int ConsoleNode::Write(size_t offs, const void* buf, size_t count) { | 186 MessagingInterface* msg_intr = mount_->ppapi()->GetMessagingInterface(); |
| 151 ConsoleInterface* con_intr = mount_->ppapi()->GetConsoleInterface(); | |
| 152 VarInterface* var_intr = mount_->ppapi()->GetVarInterface(); | 187 VarInterface* var_intr = mount_->ppapi()->GetVarInterface(); |
| 153 | 188 |
| 154 if (var_intr && con_intr) { | 189 if (!(var_intr && msg_intr)) |
| 155 const char* data = static_cast<const char *>(buf); | 190 return ENOSYS; |
| 156 uint32_t len = static_cast<uint32_t>(count); | 191 |
| 157 struct PP_Var val = var_intr->VarFromUtf8(data, len); | 192 const char* data = static_cast<const char*>(buf); |
| 158 con_intr->Log(mount_->ppapi()->GetInstance(), level_, val); | 193 uint32_t len = static_cast<uint32_t>(count); |
| 159 return count; | 194 struct PP_Var val = var_intr->VarFromUtf8(data, len); |
| 160 } | 195 msg_intr->PostMessage(mount_->ppapi()->GetInstance(), val); |
| 196 | |
| 197 *out_bytes = count; | |
| 161 return 0; | 198 return 0; |
| 162 } | 199 } |
| 163 | 200 |
| 201 ZeroNode::ZeroNode(Mount* mount) : MountNode(mount) { stat_.st_mode = S_IFCHR; } | |
| 164 | 202 |
| 165 TtyNode::TtyNode(Mount* mount) | 203 Error ZeroNode::Read(size_t offs, void* buf, size_t count, int* out_bytes) { |
| 166 : NullNode(mount) { | 204 memset(buf, 0, count); |
| 167 } | 205 *out_bytes = count; |
| 168 | |
| 169 int TtyNode::Write(size_t offs, const void* buf, size_t count) { | |
| 170 MessagingInterface* msg_intr = mount_->ppapi()->GetMessagingInterface(); | |
| 171 VarInterface* var_intr = mount_->ppapi()->GetVarInterface(); | |
| 172 | |
| 173 if (var_intr && msg_intr) { | |
| 174 const char* data = static_cast<const char *>(buf); | |
| 175 uint32_t len = static_cast<uint32_t>(count); | |
| 176 struct PP_Var val = var_intr->VarFromUtf8(data, len); | |
| 177 msg_intr->PostMessage(mount_->ppapi()->GetInstance(), val); | |
| 178 return count; | |
| 179 } | |
| 180 return 0; | 206 return 0; |
| 181 } | 207 } |
| 182 | 208 |
| 183 | 209 Error ZeroNode::Write(size_t offs, |
| 184 ZeroNode::ZeroNode(Mount* mount) | 210 const void* buf, |
| 185 : MountNode(mount) { | 211 size_t count, |
| 186 stat_.st_mode = S_IFCHR; | 212 int* out_bytes) { |
| 213 *out_bytes = count; | |
| 214 return 0; | |
| 187 } | 215 } |
| 188 | 216 |
| 189 int ZeroNode::Read(size_t offs, void* buf, size_t count) { | 217 UrandomNode::UrandomNode(Mount* mount) : MountNode(mount) { |
| 190 memset(buf, 0, count); | |
| 191 return count; | |
| 192 } | |
| 193 | |
| 194 int ZeroNode::Write(size_t offs, const void* buf, size_t count) { | |
| 195 return count; | |
| 196 } | |
| 197 | |
| 198 UrandomNode::UrandomNode(Mount* mount) | |
| 199 : MountNode(mount) { | |
| 200 stat_.st_mode = S_IFCHR; | 218 stat_.st_mode = S_IFCHR; |
| 201 #if defined(__native_client__) | 219 #if defined(__native_client__) |
| 202 size_t result = nacl_interface_query(NACL_IRT_RANDOM_v0_1, &random_interface_, | 220 size_t result = nacl_interface_query( |
| 203 sizeof(random_interface_)); | 221 NACL_IRT_RANDOM_v0_1, &random_interface_, sizeof(random_interface_)); |
| 204 interface_ok_ = result != 0; | 222 interface_ok_ = result != 0; |
| 205 #endif | 223 #endif |
| 206 } | 224 } |
| 207 | 225 |
| 208 int UrandomNode::Read(size_t offs, void* buf, size_t count) { | 226 Error UrandomNode::Read(size_t offs, void* buf, size_t count, int* out_bytes) { |
| 227 *out_bytes = 0; | |
| 228 | |
| 209 #if defined(__native_client__) | 229 #if defined(__native_client__) |
| 210 if (interface_ok_) { | 230 if (!interface_ok_) |
| 211 size_t nread; | 231 return EBADF; |
| 212 int result = (*random_interface_.get_random_bytes)(buf, count, &nread); | |
| 213 if (result != 0) { | |
| 214 errno = result; | |
| 215 return 0; | |
| 216 } | |
| 217 | 232 |
| 218 return count; | 233 size_t nread; |
| 219 } | 234 int error = (*random_interface_.get_random_bytes)(buf, count, &nread); |
| 235 if (error) | |
| 236 return error; | |
| 220 | 237 |
| 221 errno = EBADF; | 238 *out_bytes = count; |
| 222 return 0; | 239 return 0; |
| 223 #elif defined(WIN32) | 240 #elif defined(WIN32) |
| 224 char* out = static_cast<char*>(buf); | 241 char* out = static_cast<char*>(buf); |
| 225 size_t bytes_left = count; | 242 size_t bytes_left = count; |
| 226 while (bytes_left) { | 243 while (bytes_left) { |
| 227 unsigned int random_int; | 244 unsigned int random_int; |
| 228 errno_t err = rand_s(&random_int); | 245 errno_t err = rand_s(&random_int); |
| 229 if (err) { | 246 if (err) { |
| 230 errno = err; | 247 *out_bytes = count - bytes_left; |
| 231 return count - bytes_left; | 248 return err; |
| 232 } | 249 } |
| 233 | 250 |
| 234 int bytes_to_copy = std::min(bytes_left, sizeof(random_int)); | 251 int bytes_to_copy = std::min(bytes_left, sizeof(random_int)); |
| 235 memcpy(out, &random_int, bytes_to_copy); | 252 memcpy(out, &random_int, bytes_to_copy); |
| 236 out += bytes_to_copy; | 253 out += bytes_to_copy; |
| 237 bytes_left -= bytes_to_copy; | 254 bytes_left -= bytes_to_copy; |
| 238 } | 255 } |
| 239 | 256 |
| 240 return count; | 257 *out_bytes = count; |
| 258 return 0; | |
| 241 #endif | 259 #endif |
| 242 } | 260 } |
| 243 | 261 |
| 244 int UrandomNode::Write(size_t offs, const void* buf, size_t count) { | 262 Error UrandomNode::Write(size_t offs, |
| 245 return count; | 263 const void* buf, |
| 264 size_t count, | |
| 265 int* out_bytes) { | |
| 266 *out_bytes = count; | |
| 267 return 0; | |
| 246 } | 268 } |
| 247 | 269 |
| 248 | |
| 249 | |
| 250 } // namespace | 270 } // namespace |
| 251 | 271 |
| 252 MountNode *MountDev::Open(const Path& path, int mode) { | 272 Error MountDev::Open(const Path& path, int mode, MountNode** out_node) { |
| 273 *out_node = NULL; | |
| 274 | |
| 253 AutoLock lock(&lock_); | 275 AutoLock lock(&lock_); |
| 254 | 276 |
| 255 // Don't allow creating any files. | 277 // Don't allow creating any files. |
| 256 if (mode & O_CREAT) | 278 if (mode & O_CREAT) |
| 257 return NULL; | 279 return EINVAL; |
| 258 | 280 |
| 259 MountNode* node = root_->FindChild(path.Join()); | 281 MountNode* node = NULL; |
| 260 if (node) | 282 int error = root_->FindChild(path.Join(), &node); |
| 261 node->Acquire(); | 283 if (error) |
| 262 return node; | 284 return error; |
| 285 | |
| 286 node->Acquire(); | |
| 287 *out_node = node; | |
| 288 return 0; | |
| 263 } | 289 } |
| 264 | 290 |
| 265 int MountDev::Unlink(const Path& path) { | 291 Error MountDev::Unlink(const Path& path) { return EINVAL; } |
| 266 errno = EINVAL; | |
| 267 return -1; | |
| 268 } | |
| 269 | 292 |
| 270 int MountDev::Mkdir(const Path& path, int permissions) { | 293 Error MountDev::Mkdir(const Path& path, int permissions) { return EINVAL; } |
| 271 errno = EINVAL; | |
| 272 return -1; | |
| 273 } | |
| 274 | 294 |
| 275 int MountDev::Rmdir(const Path& path) { | 295 Error MountDev::Rmdir(const Path& path) { return EINVAL; } |
| 276 errno = EINVAL; | |
| 277 return -1; | |
| 278 } | |
| 279 | 296 |
| 280 int MountDev::Remove(const Path& path) { | 297 Error MountDev::Remove(const Path& path) { return EINVAL; } |
| 281 errno = EINVAL; | |
| 282 return -1; | |
| 283 } | |
| 284 | 298 |
| 285 MountDev::MountDev() | 299 MountDev::MountDev() {} |
| 286 : null_node_(NULL), | |
| 287 zero_node_(NULL), | |
| 288 random_node_(NULL), | |
| 289 console0_node_(NULL), | |
| 290 console1_node_(NULL), | |
| 291 console2_node_(NULL), | |
| 292 console3_node_(NULL), | |
| 293 tty_node_(NULL) { | |
| 294 } | |
| 295 | 300 |
| 296 bool MountDev::Init(int dev, StringMap_t& args, PepperInterface* ppapi) { | 301 #define INITIALIZE_DEV_NODE(path, klass) \ |
| 297 if (!Mount::Init(dev, args, ppapi)) | 302 error = root_->AddChild(path, new klass(this)); \ |
| 303 if (error) \ | |
| 298 return false; | 304 return false; |
| 299 | 305 |
| 306 #define INITIALIZE_DEV_NODE_1(path, klass, arg) \ | |
| 307 error = root_->AddChild(path, new klass(this, arg)); \ | |
| 308 if (error) \ | |
| 309 return false; | |
| 310 | |
| 311 Error MountDev::Init(int dev, StringMap_t& args, PepperInterface* ppapi) { | |
| 312 Error error = Mount::Init(dev, args, ppapi); | |
| 313 if (error) | |
| 314 return error; | |
| 315 | |
| 300 root_ = new MountNodeDir(this); | 316 root_ = new MountNodeDir(this); |
| 301 null_node_ = new NullNode(this); | |
| 302 root_->AddChild("/null", null_node_); | |
| 303 zero_node_ = new ZeroNode(this); | |
| 304 root_->AddChild("/zero", zero_node_); | |
| 305 random_node_ = new UrandomNode(this); | |
| 306 root_->AddChild("/urandom", random_node_); | |
| 307 | 317 |
| 308 console0_node_ = new ConsoleNode(this, PP_LOGLEVEL_TIP); | 318 INITIALIZE_DEV_NODE("/null", NullNode); |
| 309 root_->AddChild("/console0", console0_node_); | 319 INITIALIZE_DEV_NODE("/zero", ZeroNode); |
| 310 console1_node_ = new ConsoleNode(this, PP_LOGLEVEL_LOG); | 320 INITIALIZE_DEV_NODE("/urandom", UrandomNode); |
| 311 root_->AddChild("/console1", console1_node_); | 321 INITIALIZE_DEV_NODE_1("/console0", ConsoleNode, PP_LOGLEVEL_TIP); |
| 312 console2_node_ = new ConsoleNode(this, PP_LOGLEVEL_WARNING); | 322 INITIALIZE_DEV_NODE_1("/console1", ConsoleNode, PP_LOGLEVEL_LOG); |
| 313 root_->AddChild("/console2", console2_node_); | 323 INITIALIZE_DEV_NODE_1("/console2", ConsoleNode, PP_LOGLEVEL_WARNING); |
| 314 console3_node_ = new ConsoleNode(this, PP_LOGLEVEL_ERROR); | 324 INITIALIZE_DEV_NODE_1("/console3", ConsoleNode, PP_LOGLEVEL_ERROR); |
| 315 root_->AddChild("/console3", console3_node_); | 325 INITIALIZE_DEV_NODE("/tty", TtyNode); |
| 326 INITIALIZE_DEV_NODE_1("/stdin", RealNode, 0); | |
| 327 INITIALIZE_DEV_NODE_1("/stdout", RealNode, 1); | |
| 328 INITIALIZE_DEV_NODE_1("/stderr", RealNode, 2); | |
| 316 | 329 |
| 317 tty_node_ = new TtyNode(this); | 330 return 0; |
|
noelallen1
2013/06/07 21:48:43
Error
binji
2013/06/07 23:23:11
Done.
| |
| 318 root_->AddChild("/tty", tty_node_); | |
| 319 | |
| 320 stdin_node_ = new RealNode(this, 0); | |
| 321 root_->AddChild("/stdin", stdin_node_); | |
| 322 stdout_node_ = new RealNode(this, 1); | |
| 323 root_->AddChild("/stdout", stdout_node_); | |
| 324 stderr_node_ = new RealNode(this, 2); | |
| 325 root_->AddChild("/stderr", stderr_node_); | |
| 326 | |
| 327 return true; | |
| 328 } | 331 } |
| 329 | 332 |
| 330 void MountDev::Destroy() { | 333 void MountDev::Destroy() { |
| 331 ReleaseAndNullNode(&stdin_node_); | 334 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.
| |
| 332 ReleaseAndNullNode(&stdout_node_); | 335 root_->Release(); |
| 333 ReleaseAndNullNode(&stderr_node_); | 336 root_ = NULL; |
| 334 ReleaseAndNullNode(&tty_node_); | |
| 335 ReleaseAndNullNode(&console3_node_); | |
| 336 ReleaseAndNullNode(&console2_node_); | |
| 337 ReleaseAndNullNode(&console1_node_); | |
| 338 ReleaseAndNullNode(&console0_node_); | |
| 339 ReleaseAndNullNode(&random_node_); | |
| 340 ReleaseAndNullNode(&zero_node_); | |
| 341 ReleaseAndNullNode(&null_node_); | |
| 342 ReleaseAndNullNode(&root_); | |
| 343 } | 337 } |
| OLD | NEW |