1 // Copyright 2013 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.
5 #include "nacl_io/dir_node.h"
10 #include "nacl_io/log.h"
11 #include "nacl_io/osdirent.h"
12 #include "nacl_io/osinttypes.h"
13 #include "nacl_io/osstat.h"
14 #include "sdk_util/auto_lock.h"
15 #include "sdk_util/macros.h"
21 // TODO(binji): For now, just use a dummy value for the parent ino.
22 const ino_t kParentDirIno
= -1;
25 DirNode::DirNode(Filesystem
* filesystem
)
27 cache_(stat_
.st_ino
, kParentDirIno
),
30 // Directories are raadable, writable and executable by default.
31 stat_
.st_mode
|= S_IRALL
| S_IWALL
| S_IXALL
;
35 for (NodeMap_t::iterator it
= map_
.begin(); it
!= map_
.end(); ++it
) {
40 Error
DirNode::Read(const HandleAttr
& attr
,
45 LOG_TRACE("Can't read a directory.");
49 Error
DirNode::FTruncate(off_t size
) {
50 LOG_TRACE("Can't truncate a directory.");
54 Error
DirNode::Write(const HandleAttr
& attr
,
59 LOG_TRACE("Can't write to a directory.");
63 Error
DirNode::GetDents(size_t offs
,
67 AUTO_LOCK(node_lock_
);
69 return cache_
.GetDents(offs
, pdir
, size
, out_bytes
);
72 Error
DirNode::AddChild(const std::string
& name
, const ScopedNode
& node
) {
73 AUTO_LOCK(node_lock_
);
76 LOG_ERROR("Can't add child with no name.");
80 if (name
.length() >= MEMBER_SIZE(dirent
, d_name
)) {
81 LOG_ERROR("Child name is too long: %" PRIuS
" >= %" PRIuS
,
83 MEMBER_SIZE(dirent
, d_name
));
87 NodeMap_t::iterator it
= map_
.find(name
);
88 if (it
!= map_
.end()) {
89 LOG_TRACE("Can't add child \"%s\", it already exists.", name
);
99 Error
DirNode::RemoveChild(const std::string
& name
) {
100 AUTO_LOCK(node_lock_
);
101 NodeMap_t::iterator it
= map_
.find(name
);
102 if (it
!= map_
.end()) {
103 it
->second
->Unlink();
111 Error
DirNode::FindChild(const std::string
& name
, ScopedNode
* out_node
) {
112 out_node
->reset(NULL
);
114 AUTO_LOCK(node_lock_
);
115 NodeMap_t::iterator it
= map_
.find(name
);
116 if (it
== map_
.end())
119 *out_node
= it
->second
;
123 int DirNode::ChildCount() {
124 AUTO_LOCK(node_lock_
);
128 void DirNode::BuildCache_Locked() {
132 for (NodeMap_t::iterator it
= map_
.begin(), end
= map_
.end(); it
!= end
;
134 const std::string
& name
= it
->first
;
135 ino_t ino
= it
->second
->stat_
.st_ino
;
136 cache_
.AddDirent(ino
, name
.c_str(), name
.length());
142 void DirNode::ClearCache_Locked() {
143 cache_built_
= false;
147 } // namespace nacl_io