[libvfs] Add a function to remove node from directory.
Adding a function which also take Node* so that clients can have more
confidence in what they are removing.
More context: https://fuchsia-review.googlesource.com/c/fuchsia/+/249338
DX-387 #comment
TEST=CQ
Change-Id: Ia73e9c414ff393adeed2110a3c428583f9685b2f
diff --git a/sdk/lib/vfs/cpp/pseudo_dir.cc b/sdk/lib/vfs/cpp/pseudo_dir.cc
index d4b6684..6d616be 100644
--- a/sdk/lib/vfs/cpp/pseudo_dir.cc
+++ b/sdk/lib/vfs/cpp/pseudo_dir.cc
@@ -62,6 +62,18 @@
return ZX_OK;
}
+zx_status_t PseudoDir::RemoveEntry(const std::string& name, Node* node) {
+ std::lock_guard<std::mutex> guard(mutex_);
+ auto entry = entries_by_name_.find(name);
+ if (entry == entries_by_name_.end() || entry->second->node() != node) {
+ return ZX_ERR_NOT_FOUND;
+ }
+ entries_by_id_.erase(entry->second->id());
+ entries_by_name_.erase(name);
+
+ return ZX_OK;
+}
+
zx_status_t PseudoDir::Lookup(const std::string& name, Node** out_node) const {
std::lock_guard<std::mutex> guard(mutex_);
diff --git a/sdk/lib/vfs/cpp/pseudo_dir.h b/sdk/lib/vfs/cpp/pseudo_dir.h
index b562b480..188410a 100644
--- a/sdk/lib/vfs/cpp/pseudo_dir.h
+++ b/sdk/lib/vfs/cpp/pseudo_dir.h
@@ -47,6 +47,13 @@
// Returns |ZX_ERR_NOT_FOUND| if there is no node with the given name.
zx_status_t RemoveEntry(const std::string& name);
+ // Removes a directory entry with the given |name| and |node|.
+ //
+ // Returns |ZX_OK| on success.
+ // Returns |ZX_ERR_NOT_FOUND| if there is no node with the given |name| and
+ // matching |node| pointer.
+ zx_status_t RemoveEntry(const std::string& name, Node* node);
+
// Removes all directory entries.
void RemoveAllEntries();
diff --git a/sdk/lib/vfs/cpp/pseudo_dir_unittest.cc b/sdk/lib/vfs/cpp/pseudo_dir_unittest.cc
index a022b4e..857dcae 100644
--- a/sdk/lib/vfs/cpp/pseudo_dir_unittest.cc
+++ b/sdk/lib/vfs/cpp/pseudo_dir_unittest.cc
@@ -110,6 +110,23 @@
ASSERT_TRUE(dir_.IsEmpty());
}
+TEST_F(PseudoDirUnit, RemoveEntryWithNode) {
+ Init(5);
+ for (int i = 0; i < 5; i++) {
+ ASSERT_EQ(2, nodes_[i].use_count());
+ ASSERT_EQ(ZX_OK, dir_.RemoveEntry(node_names_[i], nodes_[i].get()))
+ << "for " << node_names_[i];
+
+ // cannot access
+ vfs::Node* n;
+ ASSERT_EQ(ZX_ERR_NOT_FOUND, dir_.Lookup(node_names_[i], &n))
+ << "for " << node_names_[i];
+ // check that use count went down by 1
+ ASSERT_EQ(1, nodes_[i].use_count());
+ }
+ ASSERT_TRUE(dir_.IsEmpty());
+}
+
TEST_F(PseudoDirUnit, RemoveUniqueNode) {
Init(0);
@@ -536,8 +553,9 @@
TEST_F(PseudoDirConnection, OpenSelf) {
std::string paths[] = {
".", "./",
- ".//", "././", "././/.",
- "././//", "././/", "././././/././././////./././//././/./././/././."};
+ ".//", "././",
+ "././/.", "././//",
+ "././/", "././././/././././////./././//././/./././/././."};
auto subdir = std::make_shared<vfs::PseudoDir>();
dir_.AddSharedEntry("subdir", subdir);
auto ptr = dir_.Serve();