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 rw_lock_init(&fLock, "packagefs directory"); 20 } 21 22 23 Directory::~Directory() 24 { 25 Node* child = fChildTable.Clear(true); 26 while (child != NULL) { 27 Node* next = child->NameHashTableNext(); 28 child->_SetParent(NULL); 29 child->ReleaseReference(); 30 child = next; 31 } 32 33 rw_lock_destroy(&fLock); 34 } 35 36 37 status_t 38 Directory::Init(const String& name) 39 { 40 status_t error = Node::Init(name); 41 if (error != B_OK) 42 return error; 43 44 return fChildTable.Init(); 45 } 46 47 48 mode_t 49 Directory::Mode() const 50 { 51 return S_IFDIR | S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH; 52 } 53 54 55 off_t 56 Directory::FileSize() const 57 { 58 return 0; 59 } 60 61 62 status_t 63 Directory::Read(off_t offset, void* buffer, size_t* bufferSize) 64 { 65 return B_IS_A_DIRECTORY; 66 } 67 68 69 status_t 70 Directory::Read(io_request* request) 71 { 72 return B_IS_A_DIRECTORY; 73 } 74 75 76 status_t 77 Directory::ReadSymlink(void* buffer, size_t* bufferSize) 78 { 79 return B_IS_A_DIRECTORY; 80 } 81 82 83 void 84 Directory::AddChild(Node* node) 85 { 86 ASSERT_WRITE_LOCKED_RW_LOCK(&fLock); 87 ASSERT(node->fParent == NULL); 88 89 fChildTable.Insert(node); 90 fChildList.Add(node); 91 node->_SetParent(this); 92 node->AcquireReference(); 93 } 94 95 96 void 97 Directory::RemoveChild(Node* node) 98 { 99 ASSERT_WRITE_LOCKED_RW_LOCK(&fLock); 100 ASSERT(node->fParent == this); 101 102 Node* nextNode = fChildList.GetNext(node); 103 104 fChildTable.Remove(node); 105 fChildList.Remove(node); 106 node->_SetParent(NULL); 107 node->ReleaseReference(); 108 109 // adjust directory iterators pointing to the removed child 110 for (DirectoryIteratorList::Iterator it = fIterators.GetIterator(); 111 DirectoryIterator* iterator = it.Next();) { 112 if (iterator->node == node) 113 iterator->node = nextNode; 114 } 115 } 116 117 118 Node* 119 Directory::FindChild(const StringKey& name) 120 { 121 return fChildTable.Lookup(name); 122 } 123 124 125 void 126 Directory::AddDirectoryIterator(DirectoryIterator* iterator) 127 { 128 ASSERT_WRITE_LOCKED_RW_LOCK(&fLock); 129 fIterators.Add(iterator); 130 } 131 132 133 void 134 Directory::RemoveDirectoryIterator(DirectoryIterator* iterator) 135 { 136 ASSERT_WRITE_LOCKED_RW_LOCK(&fLock); 137 fIterators.Remove(iterator); 138 } 139