xref: /haiku/src/add-ons/kernel/file_systems/packagefs/nodes/Directory.cpp (revision 9a6a20d4689307142a7ed26a1437ba47e244e73f)
1 /*
2  * Copyright 2009-2011, Ingo Weinhold, ingo_weinhold@gmx.de.
3  * Distributed under the terms of the MIT License.
4  */
5 
6 
7 #include "Directory.h"
8 
9 #include "DebugSupport.h"
10 #include "UnpackingAttributeCookie.h"
11 #include "UnpackingAttributeDirectoryCookie.h"
12 #include "Utils.h"
13 
14 
15 Directory::Directory(ino_t id)
16 	:
17 	Node(id)
18 {
19 }
20 
21 
22 Directory::~Directory()
23 {
24 	Node* child = fChildTable.Clear(true);
25 	while (child != NULL) {
26 		Node* next = child->NameHashTableNext();
27 		child->ReleaseReference();
28 		child = next;
29 	}
30 }
31 
32 
33 status_t
34 Directory::Init(const String& name)
35 {
36 	status_t error = Node::Init(name);
37 	if (error != B_OK)
38 		return error;
39 
40 	return fChildTable.Init();
41 }
42 
43 
44 mode_t
45 Directory::Mode() const
46 {
47 	return S_IFDIR | S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH;
48 }
49 
50 
51 off_t
52 Directory::FileSize() const
53 {
54 	return 0;
55 }
56 
57 
58 status_t
59 Directory::Read(off_t offset, void* buffer, size_t* bufferSize)
60 {
61 	return B_IS_A_DIRECTORY;
62 }
63 
64 
65 status_t
66 Directory::Read(io_request* request)
67 {
68 	return B_IS_A_DIRECTORY;
69 }
70 
71 
72 status_t
73 Directory::ReadSymlink(void* buffer, size_t* bufferSize)
74 {
75 	return B_IS_A_DIRECTORY;
76 }
77 
78 
79 void
80 Directory::AddChild(Node* node)
81 {
82 	ASSERT_WRITE_LOCKED_RW_LOCK(&fLock);
83 	ASSERT(node->Parent() == NULL);
84 
85 	fChildTable.Insert(node);
86 	fChildList.Add(node);
87 	node->_SetParent(this);
88 	node->AcquireReference();
89 }
90 
91 
92 void
93 Directory::RemoveChild(Node* node)
94 {
95 	ASSERT_WRITE_LOCKED_RW_LOCK(&fLock);
96 	ASSERT(node->Parent() == this);
97 
98 	Node* nextNode = fChildList.GetNext(node);
99 
100 	fChildTable.Remove(node);
101 	fChildList.Remove(node);
102 	node->_SetParent(NULL);
103 	node->ReleaseReference();
104 
105 	// adjust directory iterators pointing to the removed child
106 	for (DirectoryIteratorList::Iterator it = fIterators.GetIterator();
107 			DirectoryIterator* iterator = it.Next();) {
108 		if (iterator->node == node)
109 			iterator->node = nextNode;
110 	}
111 }
112 
113 
114 Node*
115 Directory::FindChild(const StringKey& name)
116 {
117 	return fChildTable.Lookup(name);
118 }
119 
120 
121 void
122 Directory::AddDirectoryIterator(DirectoryIterator* iterator)
123 {
124 	ASSERT_WRITE_LOCKED_RW_LOCK(&fLock);
125 	fIterators.Add(iterator);
126 }
127 
128 
129 void
130 Directory::RemoveDirectoryIterator(DirectoryIterator* iterator)
131 {
132 	ASSERT_WRITE_LOCKED_RW_LOCK(&fLock);
133 	fIterators.Remove(iterator);
134 }
135