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
, mode_t mode
)
27 cache_(stat_
.st_ino
, kParentDirIno
),
31 UpdateTime(UPDATE_ATIME
| UPDATE_MTIME
| UPDATE_CTIME
);
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 UpdateTime(UPDATE_ATIME
);
70 return cache_
.GetDents(offs
, pdir
, size
, out_bytes
);
73 Error
DirNode::Fchmod(mode_t mode
) {
74 AUTO_LOCK(node_lock_
);
76 UpdateTime(UPDATE_CTIME
);
80 Error
DirNode::AddChild(const std::string
& name
, const ScopedNode
& node
) {
81 AUTO_LOCK(node_lock_
);
84 LOG_ERROR("Can't add child with no name.");
88 if (name
.length() >= MEMBER_SIZE(dirent
, d_name
)) {
89 LOG_ERROR("Child name is too long: %" PRIuS
" >= %" PRIuS
,
91 MEMBER_SIZE(dirent
, d_name
));
95 NodeMap_t::iterator it
= map_
.find(name
);
96 if (it
!= map_
.end()) {
97 LOG_TRACE("Can't add child \"%s\", it already exists.", name
.c_str());
101 UpdateTime(UPDATE_MTIME
| UPDATE_CTIME
);
109 Error
DirNode::RemoveChild(const std::string
& name
) {
110 AUTO_LOCK(node_lock_
);
111 NodeMap_t::iterator it
= map_
.find(name
);
112 if (it
!= map_
.end()) {
113 UpdateTime(UPDATE_MTIME
| UPDATE_CTIME
);
114 it
->second
->Unlink();
122 Error
DirNode::FindChild(const std::string
& name
, ScopedNode
* out_node
) {
123 out_node
->reset(NULL
);
125 AUTO_LOCK(node_lock_
);
126 NodeMap_t::iterator it
= map_
.find(name
);
127 if (it
== map_
.end())
130 *out_node
= it
->second
;
134 int DirNode::ChildCount() {
135 AUTO_LOCK(node_lock_
);
139 void DirNode::BuildCache_Locked() {
143 for (NodeMap_t::iterator it
= map_
.begin(), end
= map_
.end(); it
!= end
;
145 const std::string
& name
= it
->first
;
146 ino_t ino
= it
->second
->stat_
.st_ino
;
147 cache_
.AddDirent(ino
, name
.c_str(), name
.length());
153 void DirNode::ClearCache_Locked() {
154 cache_built_
= false;
158 } // namespace nacl_io