* Copyright 2009-2011, Ingo Weinhold, ingo_weinhold@gmx.de.
* Distributed under the terms of the MIT License.
*/
#include "Directory.h"
#include "DebugSupport.h"
#include "UnpackingAttributeCookie.h"
#include "UnpackingAttributeDirectoryCookie.h"
#include "Utils.h"
Directory::Directory(ino_t id)
:
Node(id)
{
rw_lock_init(&fLock, "packagefs directory");
}
Directory::~Directory()
{
Node* child = fChildTable.Clear(true);
while (child != NULL) {
Node* next = child->NameHashTableNext();
child->_SetParent(NULL);
child->ReleaseReference();
child = next;
}
rw_lock_destroy(&fLock);
}
status_t
Directory::Init(const String& name)
{
status_t error = Node::Init(name);
if (error != B_OK)
return error;
return fChildTable.Init();
}
mode_t
Directory::Mode() const
{
return S_IFDIR | S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH;
}
off_t
Directory::FileSize() const
{
return 0;
}
status_t
Directory::Read(off_t offset, void* buffer, size_t* bufferSize)
{
return B_IS_A_DIRECTORY;
}
status_t
Directory::Read(io_request* request)
{
return B_IS_A_DIRECTORY;
}
status_t
Directory::ReadSymlink(void* buffer, size_t* bufferSize)
{
return B_IS_A_DIRECTORY;
}
void
Directory::AddChild(Node* node)
{
ASSERT_WRITE_LOCKED_RW_LOCK(&fLock);
ASSERT(node->fParent == NULL);
fChildTable.Insert(node);
fChildList.Add(node);
node->_SetParent(this);
node->AcquireReference();
}
void
Directory::RemoveChild(Node* node)
{
ASSERT_WRITE_LOCKED_RW_LOCK(&fLock);
ASSERT(node->fParent == this);
Node* nextNode = fChildList.GetNext(node);
fChildTable.Remove(node);
fChildList.Remove(node);
node->_SetParent(NULL);
node->ReleaseReference();
for (DirectoryIteratorList::Iterator it = fIterators.GetIterator();
DirectoryIterator* iterator = it.Next();) {
if (iterator->node == node)
iterator->node = nextNode;
}
}
Node*
Directory::FindChild(const StringKey& name)
{
return fChildTable.Lookup(name);
}
void
Directory::AddDirectoryIterator(DirectoryIterator* iterator)
{
ASSERT_WRITE_LOCKED_RW_LOCK(&fLock);
fIterators.Add(iterator);
}
void
Directory::RemoveDirectoryIterator(DirectoryIterator* iterator)
{
ASSERT_WRITE_LOCKED_RW_LOCK(&fLock);
fIterators.Remove(iterator);
}