diff --git a/src/add-ons/kernel/file_systems/packagefs/Directory.cpp b/src/add-ons/kernel/file_systems/packagefs/Directory.cpp index 20d36a31d2..c073dc06ba 100644 --- a/src/add-ons/kernel/file_systems/packagefs/Directory.cpp +++ b/src/add-ons/kernel/file_systems/packagefs/Directory.cpp @@ -31,13 +31,13 @@ Directory::~Directory() status_t -Directory::Init(Directory* parent, const char* name) +Directory::Init(Directory* parent, const char* name, uint32 flags) { - status_t error = fChildTable.Init(); + status_t error = Node::Init(parent, name, flags); if (error != B_OK) return error; - return Node::Init(parent, name); + return fChildTable.Init(); } diff --git a/src/add-ons/kernel/file_systems/packagefs/Directory.h b/src/add-ons/kernel/file_systems/packagefs/Directory.h index 1b30aad3b0..3dc604cd37 100644 --- a/src/add-ons/kernel/file_systems/packagefs/Directory.h +++ b/src/add-ons/kernel/file_systems/packagefs/Directory.h @@ -27,7 +27,8 @@ public: Directory(ino_t id); virtual ~Directory(); - virtual status_t Init(Directory* parent, const char* name); + virtual status_t Init(Directory* parent, const char* name, + uint32 flags); virtual status_t Read(off_t offset, void* buffer, size_t* bufferSize); diff --git a/src/add-ons/kernel/file_systems/packagefs/Node.cpp b/src/add-ons/kernel/file_systems/packagefs/Node.cpp index d685b93e8f..2ed70e2669 100644 --- a/src/add-ons/kernel/file_systems/packagefs/Node.cpp +++ b/src/add-ons/kernel/file_systems/packagefs/Node.cpp @@ -16,7 +16,8 @@ Node::Node(ino_t id) : fID(id), fParent(NULL), - fName(NULL) + fName(NULL), + fFlags(0) { rw_lock_init(&fLock, "packagefs node"); } @@ -24,19 +25,28 @@ Node::Node(ino_t id) Node::~Node() { -PRINT("%p->Node::~Node()\n", this); - free(fName); + if ((fFlags & NODE_FLAG_OWNS_NAME) != 0) + free(fName); + rw_lock_destroy(&fLock); } status_t -Node::Init(Directory* parent, const char* name) +Node::Init(Directory* parent, const char* name, uint32 flags) { fParent = parent; - fName = strdup(name); - if (fName == NULL) - RETURN_ERROR(B_NO_MEMORY); + fFlags = flags; + + if ((flags & NODE_FLAG_CONST_NAME) != 0 + || (flags & NODE_FLAG_KEEP_NAME) != 0) { + fName = const_cast(name); + } else { + fName = strdup(name); + if (fName == NULL) + RETURN_ERROR(B_NO_MEMORY); + fFlags |= NODE_FLAG_OWNS_NAME; + } return B_OK; } diff --git a/src/add-ons/kernel/file_systems/packagefs/Node.h b/src/add-ons/kernel/file_systems/packagefs/Node.h index 80535aa928..33ba885b48 100644 --- a/src/add-ons/kernel/file_systems/packagefs/Node.h +++ b/src/add-ons/kernel/file_systems/packagefs/Node.h @@ -23,6 +23,18 @@ class Directory; class PackageNode; +// node flags +enum { + NODE_FLAG_KEEP_NAME = 0x01, + // Init(): Take over ownership of the given name (i.e. free in + // destructor). + NODE_FLAG_CONST_NAME = 0x02, + // Init(): The given name is a constant that won't go away during the + // lifetime of the object. No need to copy. + NODE_FLAG_OWNS_NAME = NODE_FLAG_CONST_NAME +}; + + class Node : public BReferenceable, public DoublyLinkedListLinkImpl { public: Node(ino_t id); @@ -42,7 +54,10 @@ public: Node*& IDHashTableNext() { return fIDHashTableNext; } - virtual status_t Init(Directory* parent, const char* name); + virtual status_t Init(Directory* parent, const char* name, + uint32 flags); + // If specified to keep the name, it does + // so also on error. virtual status_t VFSInit(dev_t deviceID); virtual void VFSUninit(); @@ -75,6 +90,7 @@ protected: char* fName; Node* fNameHashTableNext; Node* fIDHashTableNext; + uint32 fFlags; }; diff --git a/src/add-ons/kernel/file_systems/packagefs/PackageFSRoot.cpp b/src/add-ons/kernel/file_systems/packagefs/PackageFSRoot.cpp index 6684de86d8..aa4dcb8bae 100644 --- a/src/add-ons/kernel/file_systems/packagefs/PackageFSRoot.cpp +++ b/src/add-ons/kernel/file_systems/packagefs/PackageFSRoot.cpp @@ -60,7 +60,7 @@ PackageFSRoot::Init() return B_NO_MEMORY; status_t error = fPackageLinksDirectory->Init(NULL, - kPackageLinksDirectoryName); + kPackageLinksDirectoryName, 0); if (error != B_OK) RETURN_ERROR(error); diff --git a/src/add-ons/kernel/file_systems/packagefs/PackageLinkDirectory.cpp b/src/add-ons/kernel/file_systems/packagefs/PackageLinkDirectory.cpp index 15701f0866..0c1aae5ed4 100644 --- a/src/add-ons/kernel/file_systems/packagefs/PackageLinkDirectory.cpp +++ b/src/add-ons/kernel/file_systems/packagefs/PackageLinkDirectory.cpp @@ -61,11 +61,6 @@ public: { } - virtual status_t Init(Directory* parent, const char* name) - { - return Node::Init(parent, name); - } - virtual mode_t Mode() const { return S_IFLNK | S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH @@ -162,7 +157,7 @@ PackageLinkDirectory::Init(Directory* parent, Package* package) if (fSelfLink == NULL) return B_NO_MEMORY; - status_t error = fSelfLink->Init(this, kSelfLinkName); + status_t error = fSelfLink->Init(this, kSelfLinkName, NODE_FLAG_CONST_NAME); if (error != B_OK) RETURN_ERROR(error); @@ -182,7 +177,6 @@ PackageLinkDirectory::Init(Directory* parent, Package* package) char* name = (char*)malloc(size); if (name == NULL) return B_NO_MEMORY; - MemoryDeleter nameDeleter(name); memcpy(name, package->Name(), nameLength + 1); if (version != NULL) { @@ -191,8 +185,7 @@ PackageLinkDirectory::Init(Directory* parent, Package* package) } // init the directory/node - error = Init(parent, name); - // TODO: This copies the name unnecessarily! + error = Init(parent, name, NODE_FLAG_KEEP_NAME); if (error != B_OK) RETURN_ERROR(error); @@ -204,9 +197,9 @@ PackageLinkDirectory::Init(Directory* parent, Package* package) status_t -PackageLinkDirectory::Init(Directory* parent, const char* name) +PackageLinkDirectory::Init(Directory* parent, const char* name, uint32 flags) { - return Directory::Init(parent, name); + return Directory::Init(parent, name, flags); } diff --git a/src/add-ons/kernel/file_systems/packagefs/PackageLinkDirectory.h b/src/add-ons/kernel/file_systems/packagefs/PackageLinkDirectory.h index b5fa320038..b32c07a6e7 100644 --- a/src/add-ons/kernel/file_systems/packagefs/PackageLinkDirectory.h +++ b/src/add-ons/kernel/file_systems/packagefs/PackageLinkDirectory.h @@ -19,7 +19,8 @@ public: virtual ~PackageLinkDirectory(); status_t Init(Directory* parent, Package* package); - virtual status_t Init(Directory* parent, const char* name); + virtual status_t Init(Directory* parent, const char* name, + uint32 flags); virtual mode_t Mode() const; virtual uid_t UserID() const; diff --git a/src/add-ons/kernel/file_systems/packagefs/PackageLinksDirectory.cpp b/src/add-ons/kernel/file_systems/packagefs/PackageLinksDirectory.cpp index 56a0514eca..d7cd7f6d8b 100644 --- a/src/add-ons/kernel/file_systems/packagefs/PackageLinksDirectory.cpp +++ b/src/add-ons/kernel/file_systems/packagefs/PackageLinksDirectory.cpp @@ -30,13 +30,6 @@ PackageLinksDirectory::~PackageLinksDirectory() } -status_t -PackageLinksDirectory::Init(Directory* parent, const char* name) -{ - return Directory::Init(parent, name); -} - - mode_t PackageLinksDirectory::Mode() const { diff --git a/src/add-ons/kernel/file_systems/packagefs/PackageLinksDirectory.h b/src/add-ons/kernel/file_systems/packagefs/PackageLinksDirectory.h index 00cea75715..4d5e3f1d0c 100644 --- a/src/add-ons/kernel/file_systems/packagefs/PackageLinksDirectory.h +++ b/src/add-ons/kernel/file_systems/packagefs/PackageLinksDirectory.h @@ -18,8 +18,6 @@ public: PackageLinksDirectory(); virtual ~PackageLinksDirectory(); - virtual status_t Init(Directory* parent, const char* name); - virtual mode_t Mode() const; virtual uid_t UserID() const; virtual gid_t GroupID() const; diff --git a/src/add-ons/kernel/file_systems/packagefs/UnpackingDirectory.cpp b/src/add-ons/kernel/file_systems/packagefs/UnpackingDirectory.cpp index 9d6046edaf..dad396e1e9 100644 --- a/src/add-ons/kernel/file_systems/packagefs/UnpackingDirectory.cpp +++ b/src/add-ons/kernel/file_systems/packagefs/UnpackingDirectory.cpp @@ -27,13 +27,6 @@ UnpackingDirectory::~UnpackingDirectory() } -status_t -UnpackingDirectory::Init(Directory* parent, const char* name) -{ - return Directory::Init(parent, name); -} - - mode_t UnpackingDirectory::Mode() const { diff --git a/src/add-ons/kernel/file_systems/packagefs/UnpackingDirectory.h b/src/add-ons/kernel/file_systems/packagefs/UnpackingDirectory.h index 79fcd8f5dc..ce2b4a8578 100644 --- a/src/add-ons/kernel/file_systems/packagefs/UnpackingDirectory.h +++ b/src/add-ons/kernel/file_systems/packagefs/UnpackingDirectory.h @@ -16,8 +16,6 @@ public: UnpackingDirectory(ino_t id); virtual ~UnpackingDirectory(); - virtual status_t Init(Directory* parent, const char* name); - virtual mode_t Mode() const; virtual uid_t UserID() const; virtual gid_t GroupID() const; diff --git a/src/add-ons/kernel/file_systems/packagefs/UnpackingLeafNode.cpp b/src/add-ons/kernel/file_systems/packagefs/UnpackingLeafNode.cpp index a1af6c0c3a..6504ac718a 100644 --- a/src/add-ons/kernel/file_systems/packagefs/UnpackingLeafNode.cpp +++ b/src/add-ons/kernel/file_systems/packagefs/UnpackingLeafNode.cpp @@ -27,13 +27,6 @@ UnpackingLeafNode::~UnpackingLeafNode() } -status_t -UnpackingLeafNode::Init(Directory* parent, const char* name) -{ - return Node::Init(parent, name); -} - - status_t UnpackingLeafNode::VFSInit(dev_t deviceID) { diff --git a/src/add-ons/kernel/file_systems/packagefs/UnpackingLeafNode.h b/src/add-ons/kernel/file_systems/packagefs/UnpackingLeafNode.h index a933bb98e9..3ebffbd28b 100644 --- a/src/add-ons/kernel/file_systems/packagefs/UnpackingLeafNode.h +++ b/src/add-ons/kernel/file_systems/packagefs/UnpackingLeafNode.h @@ -16,8 +16,6 @@ public: UnpackingLeafNode(ino_t id); virtual ~UnpackingLeafNode(); - virtual status_t Init(Directory* parent, const char* name); - virtual status_t VFSInit(dev_t deviceID); virtual void VFSUninit(); diff --git a/src/add-ons/kernel/file_systems/packagefs/Volume.cpp b/src/add-ons/kernel/file_systems/packagefs/Volume.cpp index 332d72eb28..5cfb0bf107 100644 --- a/src/add-ons/kernel/file_systems/packagefs/Volume.cpp +++ b/src/add-ons/kernel/file_systems/packagefs/Volume.cpp @@ -511,7 +511,8 @@ Volume::Mount(const char* parameterString) = new(std::nothrow) ::RootDirectory(kRootDirectoryID, st.st_mtim); if (fRootDirectory == NULL) RETURN_ERROR(B_NO_MEMORY); - fRootDirectory->Init(NULL, volumeName != NULL ? volumeName : "Package FS"); + fRootDirectory->Init(NULL, volumeName != NULL ? volumeName : "Package FS", + 0); fNodes.Insert(fRootDirectory); // get our mount point @@ -1101,7 +1102,7 @@ Volume::_CreateUnpackingNode(mode_t mode, Directory* parent, const char* name, Node* node = unpackingNode->GetNode(); BReference nodeReference(node, true); - status_t error = node->Init(parent, name); + status_t error = node->Init(parent, name, 0); if (error != B_OK) RETURN_ERROR(error);