| 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 #include "nacl_io/mount_node_dir.h" | 5 #include "nacl_io/mount_node_dir.h" |
| 6 | 6 |
| 7 #include <errno.h> | 7 #include <errno.h> |
| 8 #include <string.h> | 8 #include <string.h> |
| 9 | 9 |
| 10 #include "nacl_io/osdirent.h" | 10 #include "nacl_io/osdirent.h" |
| (...skipping 26 matching lines...) Expand all Loading... |
| 37 *out_bytes = 0; | 37 *out_bytes = 0; |
| 38 return EISDIR; | 38 return EISDIR; |
| 39 } | 39 } |
| 40 | 40 |
| 41 Error MountNodeDir::GetDents(size_t offs, | 41 Error MountNodeDir::GetDents(size_t offs, |
| 42 struct dirent* pdir, | 42 struct dirent* pdir, |
| 43 size_t size, | 43 size_t size, |
| 44 int* out_bytes) { | 44 int* out_bytes) { |
| 45 *out_bytes = 0; | 45 *out_bytes = 0; |
| 46 | 46 |
| 47 AutoLock lock(&lock_); | 47 AUTO_LOCK(node_lock_); |
| 48 | 48 |
| 49 // If the buffer pointer is invalid, fail | 49 // If the buffer pointer is invalid, fail |
| 50 if (NULL == pdir) | 50 if (NULL == pdir) |
| 51 return EINVAL; | 51 return EINVAL; |
| 52 | 52 |
| 53 // If the buffer is too small, fail | 53 // If the buffer is too small, fail |
| 54 if (size < sizeof(struct dirent)) | 54 if (size < sizeof(struct dirent)) |
| 55 return EINVAL; | 55 return EINVAL; |
| 56 | 56 |
| 57 // Force size to a multiple of dirent | 57 // Force size to a multiple of dirent |
| (...skipping 10 matching lines...) Expand all Loading... |
| 68 if (offs + size >= max) | 68 if (offs + size >= max) |
| 69 size = max - offs; | 69 size = max - offs; |
| 70 | 70 |
| 71 memcpy(pdir, ((char*)cache_) + offs, size); | 71 memcpy(pdir, ((char*)cache_) + offs, size); |
| 72 *out_bytes = size; | 72 *out_bytes = size; |
| 73 return 0; | 73 return 0; |
| 74 } | 74 } |
| 75 | 75 |
| 76 Error MountNodeDir::AddChild(const std::string& name, | 76 Error MountNodeDir::AddChild(const std::string& name, |
| 77 const ScopedMountNode& node) { | 77 const ScopedMountNode& node) { |
| 78 AutoLock lock(&lock_); | 78 AUTO_LOCK(node_lock_); |
| 79 | 79 |
| 80 if (name.empty()) | 80 if (name.empty()) |
| 81 return ENOENT; | 81 return ENOENT; |
| 82 | 82 |
| 83 if (name.length() >= MEMBER_SIZE(struct dirent, d_name)) | 83 if (name.length() >= MEMBER_SIZE(struct dirent, d_name)) |
| 84 return ENAMETOOLONG; | 84 return ENAMETOOLONG; |
| 85 | 85 |
| 86 MountNodeMap_t::iterator it = map_.find(name); | 86 MountNodeMap_t::iterator it = map_.find(name); |
| 87 if (it != map_.end()) | 87 if (it != map_.end()) |
| 88 return EEXIST; | 88 return EEXIST; |
| 89 | 89 |
| 90 node->Link(); | 90 node->Link(); |
| 91 map_[name] = node; | 91 map_[name] = node; |
| 92 ClearCache(); | 92 ClearCache(); |
| 93 return 0; | 93 return 0; |
| 94 } | 94 } |
| 95 | 95 |
| 96 Error MountNodeDir::RemoveChild(const std::string& name) { | 96 Error MountNodeDir::RemoveChild(const std::string& name) { |
| 97 AutoLock lock(&lock_); | 97 AUTO_LOCK(node_lock_); |
| 98 MountNodeMap_t::iterator it = map_.find(name); | 98 MountNodeMap_t::iterator it = map_.find(name); |
| 99 if (it != map_.end()) { | 99 if (it != map_.end()) { |
| 100 it->second->Unlink(); | 100 it->second->Unlink(); |
| 101 map_.erase(it); | 101 map_.erase(it); |
| 102 ClearCache(); | 102 ClearCache(); |
| 103 return 0; | 103 return 0; |
| 104 } | 104 } |
| 105 return ENOENT; | 105 return ENOENT; |
| 106 } | 106 } |
| 107 | 107 |
| 108 Error MountNodeDir::FindChild(const std::string& name, | 108 Error MountNodeDir::FindChild(const std::string& name, |
| 109 ScopedMountNode* out_node) { | 109 ScopedMountNode* out_node) { |
| 110 out_node->reset(NULL); | 110 out_node->reset(NULL); |
| 111 | 111 |
| 112 AutoLock lock(&lock_); | 112 AUTO_LOCK(node_lock_); |
| 113 MountNodeMap_t::iterator it = map_.find(name); | 113 MountNodeMap_t::iterator it = map_.find(name); |
| 114 if (it == map_.end()) | 114 if (it == map_.end()) |
| 115 return ENOENT; | 115 return ENOENT; |
| 116 | 116 |
| 117 *out_node = it->second; | 117 *out_node = it->second; |
| 118 return 0; | 118 return 0; |
| 119 } | 119 } |
| 120 | 120 |
| 121 int MountNodeDir::ChildCount() { | 121 int MountNodeDir::ChildCount() { |
| 122 AutoLock lock(&lock_); | 122 AUTO_LOCK(node_lock_); |
| 123 return map_.size(); | 123 return map_.size(); |
| 124 } | 124 } |
| 125 | 125 |
| 126 void MountNodeDir::ClearCache() { | 126 void MountNodeDir::ClearCache() { |
| 127 free(cache_); | 127 free(cache_); |
| 128 cache_ = NULL; | 128 cache_ = NULL; |
| 129 } | 129 } |
| 130 | 130 |
| 131 void MountNodeDir::BuildCache() { | 131 void MountNodeDir::BuildCache() { |
| 132 if (map_.size()) { | 132 if (map_.size()) { |
| 133 cache_ = (struct dirent*)malloc(sizeof(struct dirent) * map_.size()); | 133 cache_ = (struct dirent*)malloc(sizeof(struct dirent) * map_.size()); |
| 134 MountNodeMap_t::iterator it = map_.begin(); | 134 MountNodeMap_t::iterator it = map_.begin(); |
| 135 for (size_t index = 0; it != map_.end(); it++, index++) { | 135 for (size_t index = 0; it != map_.end(); it++, index++) { |
| 136 size_t len = it->first.length(); | 136 size_t len = it->first.length(); |
| 137 cache_[index].d_ino = it->second->stat_.st_ino; | 137 cache_[index].d_ino = it->second->stat_.st_ino; |
| 138 cache_[index].d_off = sizeof(struct dirent); | 138 cache_[index].d_off = sizeof(struct dirent); |
| 139 cache_[index].d_reclen = sizeof(struct dirent); | 139 cache_[index].d_reclen = sizeof(struct dirent); |
| 140 cache_[index].d_name[len] = 0; | 140 cache_[index].d_name[len] = 0; |
| 141 strncpy(cache_[index].d_name, &it->first[0], len); | 141 strncpy(cache_[index].d_name, &it->first[0], len); |
| 142 } | 142 } |
| 143 } | 143 } |
| 144 } | 144 } |
| 145 | 145 |
| OLD | NEW |