* Implemented intermediate base class PackageLeafNode for PackageFile and

PackageSymlink with a "fat" interface.
* Replaced File and Symlink by fat class LeafNode.
* Added Package* object management to Directory and LeafNode.
* Implemented packagefs_read_symlink(), so symlinks work now.
* Added some missing locking the kernel interface.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@34096 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ingo Weinhold 2009-11-17 16:10:21 +00:00
parent 9d6405b724
commit 694cb0b270
22 changed files with 336 additions and 168 deletions

View File

@ -7,14 +7,12 @@
#include "Directory.h"
#include "DebugSupport.h"
#include "PackageDirectory.h"
Directory::Directory(ino_t id)
:
Node(id)
{
fMode = S_IFDIR | S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH;
}
@ -40,13 +38,43 @@ Directory::Init(Directory* parent, const char* name)
}
mode_t
Directory::Mode() const
{
if (PackageDirectory* packageDirectory = fPackageDirectories.Head())
return packageDirectory->Mode();
return S_IFDIR | S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH;
}
uid_t
Directory::UserID() const
{
if (PackageDirectory* packageDirectory = fPackageDirectories.Head())
return packageDirectory->UserID();
return 0;
}
gid_t
Directory::GroupID() const
{
if (PackageDirectory* packageDirectory = fPackageDirectories.Head())
return packageDirectory->GroupID();
return 0;
}
status_t
Directory::AddPackageNode(PackageNode* packageNode)
{
if (!S_ISDIR(packageNode->Mode()))
return B_BAD_VALUE;
// TODO:...
PackageDirectory* packageDirectory
= dynamic_cast<PackageDirectory*>(packageNode);
fPackageDirectories.Add(packageDirectory);
return B_OK;
}

View File

@ -7,6 +7,7 @@
#include "Node.h"
#include "PackageDirectory.h"
@ -30,6 +31,10 @@ public:
virtual status_t Init(Directory* parent, const char* name);
virtual mode_t Mode() const;
virtual uid_t UserID() const;
virtual gid_t GroupID() const;
virtual status_t AddPackageNode(PackageNode* packageNode);
void AddChild(Node* node);
@ -47,6 +52,7 @@ public:
private:
NodeNameHashTable fChildTable;
NodeList fChildList;
PackageDirectoryList fPackageDirectories;
DirectoryIteratorList fIterators;
};

View File

@ -1,41 +0,0 @@
/*
* Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
* Distributed under the terms of the MIT License.
*/
#include "File.h"
#include "PackageFile.h"
File::File(ino_t id)
:
Node(id)
{
fMode = S_IFREG | S_IRUSR | S_IRGRP | S_IROTH;
}
File::~File()
{
}
status_t
File::Init(Directory* parent, const char* name)
{
return Node::Init(parent, name);
}
status_t
File::AddPackageNode(PackageNode* packageNode)
{
if (!S_ISREG(packageNode->Mode()))
return B_BAD_VALUE;
// TODO:...
return B_OK;
}

View File

@ -1,23 +0,0 @@
/*
* Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
* Distributed under the terms of the MIT License.
*/
#ifndef FILE_H
#define FILE_H
#include "Node.h"
class File : public Node {
public:
File(ino_t id);
virtual ~File();
virtual status_t Init(Directory* parent, const char* name);
virtual status_t AddPackageNode(PackageNode* packageNode);
};
#endif // FILE_H

View File

@ -12,16 +12,16 @@ DEFINES += B_ENABLE_INCOMPLETE_POSIX_AT_SUPPORT ;
HAIKU_PACKAGE_FS_SOURCES =
DebugSupport.cpp
Directory.cpp
File.cpp
kernel_interface.cpp
LeafNode.cpp
Node.cpp
Package.cpp
PackageDirectory.cpp
PackageDomain.cpp
PackageFile.cpp
PackageLeafNode.cpp
PackageNode.cpp
PackageSymlink.cpp
Symlink.cpp
Volume.cpp
;

View File

@ -0,0 +1,74 @@
/*
* Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
* Distributed under the terms of the MIT License.
*/
#include "LeafNode.h"
LeafNode::LeafNode(ino_t id)
:
Node(id)
{
}
LeafNode::~LeafNode()
{
}
status_t
LeafNode::Init(Directory* parent, const char* name)
{
return Node::Init(parent, name);
}
mode_t
LeafNode::Mode() const
{
if (PackageLeafNode* packageNode = fPackageNodes.Head())
return packageNode->Mode();
return S_IFREG | S_IRUSR | S_IRGRP | S_IROTH;
}
uid_t
LeafNode::UserID() const
{
if (PackageLeafNode* packageNode = fPackageNodes.Head())
return packageNode->UserID();
return 0;
}
gid_t
LeafNode::GroupID() const
{
if (PackageLeafNode* packageNode = fPackageNodes.Head())
return packageNode->GroupID();
return 0;
}
status_t
LeafNode::AddPackageNode(PackageNode* packageNode)
{
if (S_ISDIR(packageNode->Mode()))
return B_BAD_VALUE;
fPackageNodes.Add(dynamic_cast<PackageLeafNode*>(packageNode));
return B_OK;
}
const char*
LeafNode::SymlinkPath() const
{
if (PackageLeafNode* packageNode = fPackageNodes.Head())
return packageNode->SymlinkPath();
return NULL;
}

View File

@ -0,0 +1,33 @@
/*
* Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
* Distributed under the terms of the MIT License.
*/
#ifndef LEAF_NODE_H
#define LEAF_NODE_H
#include "Node.h"
#include "PackageLeafNode.h"
class LeafNode : public Node {
public:
LeafNode(ino_t id);
virtual ~LeafNode();
virtual status_t Init(Directory* parent, const char* name);
virtual mode_t Mode() const;
virtual uid_t UserID() const;
virtual gid_t GroupID() const;
virtual status_t AddPackageNode(PackageNode* packageNode);
const char* SymlinkPath() const;
private:
PackageLeafNodeList fPackageNodes;
};
#endif // LEAF_NODE_H

View File

@ -40,12 +40,12 @@ public:
Node*& IDHashTableNext()
{ return fIDHashTableNext; }
mode_t Mode() const { return fMode; }
uid_t UserID() const { return fUserID; }
gid_t GroupID() const { return fGroupID; }
virtual status_t Init(Directory* parent, const char* name);
virtual mode_t Mode() const = 0;
virtual uid_t UserID() const = 0;
virtual gid_t GroupID() const = 0;
virtual status_t AddPackageNode(PackageNode* packageNode) = 0;
protected:

View File

@ -7,7 +7,9 @@
#include "PackageDirectory.h"
PackageDirectory::PackageDirectory()
PackageDirectory::PackageDirectory(mode_t mode)
:
PackageNode(mode)
{
}

View File

@ -6,12 +6,15 @@
#define PACKAGE_DIRECTORY_H
#include <util/DoublyLinkedList.h>
#include "PackageNode.h"
class PackageDirectory : public PackageNode {
class PackageDirectory : public PackageNode,
public DoublyLinkedListLinkImpl<PackageDirectory> {
public:
PackageDirectory();
PackageDirectory(mode_t mode);
virtual ~PackageDirectory();
void AddChild(PackageNode* node);
@ -42,4 +45,7 @@ PackageDirectory::NextChild(PackageNode* node) const
}
typedef DoublyLinkedList<PackageDirectory> PackageDirectoryList;
#endif // PACKAGE_DIRECTORY_H

View File

@ -7,7 +7,10 @@
#include "PackageFile.h"
PackageFile::PackageFile()
PackageFile::PackageFile(mode_t mode, const PackageData& data)
:
PackageLeafNode(mode),
fData(data)
{
}

View File

@ -6,13 +6,19 @@
#define PACKAGE_FILE_H
#include "PackageNode.h"
#include "PackageData.h"
#include "PackageLeafNode.h"
class PackageFile : public PackageNode {
class PackageFile : public PackageLeafNode {
public:
PackageFile();
PackageFile(mode_t mode,
const PackageData& data);
virtual ~PackageFile();
private:
PackageData fData;
};

View File

@ -0,0 +1,26 @@
/*
* Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
* Distributed under the terms of the MIT License.
*/
#include "PackageLeafNode.h"
PackageLeafNode::PackageLeafNode(mode_t mode)
:
PackageNode(mode)
{
}
PackageLeafNode::~PackageLeafNode()
{
}
const char*
PackageLeafNode::SymlinkPath() const
{
return NULL;
}

View File

@ -0,0 +1,32 @@
/*
* Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
* Distributed under the terms of the MIT License.
*/
#ifndef PACKAGE_LEAF_NODE_H
#define PACKAGE_LEAF_NODE_H
#include "PackageNode.h"
class PackageData;
class PackageLeafNode : public PackageNode {
public:
PackageLeafNode(mode_t mode);
virtual ~PackageLeafNode();
virtual const char* SymlinkPath() const;
public:
SinglyLinkedListLink<PackageLeafNode> fListLink;
};
typedef SinglyLinkedList<PackageLeafNode,
SinglyLinkedListMemberGetLink<PackageLeafNode,
&PackageLeafNode::fListLink> > PackageLeafNodeList;
#endif // PACKAGE_LEAF_NODE_H

View File

@ -12,10 +12,13 @@
#include "DebugSupport.h"
PackageNode::PackageNode()
PackageNode::PackageNode(mode_t mode)
:
fParent(NULL),
fName(NULL)
fName(NULL),
fMode(mode),
fUserID(0),
fGroupID(0)
{
}

View File

@ -16,7 +16,7 @@ class PackageDirectory;
class PackageNode : public SinglyLinkedListLinkImpl<PackageNode> {
public:
PackageNode();
PackageNode(mode_t mode);
virtual ~PackageNode();
PackageDirectory* Parent() const { return fParent; }
@ -25,13 +25,20 @@ public:
virtual status_t Init(PackageDirectory* parent,
const char* name);
void SetMode(mode_t mode) { fMode = mode; }
mode_t Mode() const { return fMode; }
private:
uid_t UserID() const { return fUserID; }
void SetUserID(uid_t id) { fUserID = id; }
gid_t GroupID() const { return fGroupID; }
void SetGroupID(gid_t id) { fGroupID = id; }
protected:
PackageDirectory* fParent;
char* fName;
mode_t fMode;
uid_t fUserID;
gid_t fGroupID;
};

View File

@ -6,12 +6,37 @@
#include "PackageSymlink.h"
#include <stdlib.h>
#include <string.h>
PackageSymlink::PackageSymlink()
PackageSymlink::PackageSymlink(mode_t mode)
:
PackageLeafNode(mode),
fSymlinkPath(NULL)
{
}
PackageSymlink::~PackageSymlink()
{
free(fSymlinkPath);
}
status_t
PackageSymlink::SetSymlinkPath(const char* path)
{
if (path == NULL)
return B_OK;
fSymlinkPath = strdup(path);
return fSymlinkPath != NULL ? B_OK : B_NO_MEMORY;
}
const char*
PackageSymlink::SymlinkPath() const
{
return fSymlinkPath;
}

View File

@ -6,13 +6,20 @@
#define PACKAGE_SYMLINK_H
#include "PackageNode.h"
#include "PackageLeafNode.h"
class PackageSymlink : public PackageNode {
class PackageSymlink : public PackageLeafNode {
public:
PackageSymlink();
PackageSymlink(mode_t mode);
virtual ~PackageSymlink();
status_t SetSymlinkPath(const char* path);
virtual const char* SymlinkPath() const;
private:
char* fSymlinkPath;
};

View File

@ -1,41 +0,0 @@
/*
* Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
* Distributed under the terms of the MIT License.
*/
#include "Symlink.h"
#include "PackageSymlink.h"
Symlink::Symlink(ino_t id)
:
Node(id)
{
fMode = S_IFLNK | S_IRUSR | S_IRGRP | S_IROTH;
}
Symlink::~Symlink()
{
}
status_t
Symlink::Init(Directory* parent, const char* name)
{
return Node::Init(parent, name);
}
status_t
Symlink::AddPackageNode(PackageNode* packageNode)
{
if (!S_ISLNK(packageNode->Mode()))
return B_BAD_VALUE;
// TODO:...
return B_OK;
}

View File

@ -1,23 +0,0 @@
/*
* Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
* Distributed under the terms of the MIT License.
*/
#ifndef SYMLINK_H
#define SYMLINK_H
#include "Node.h"
class Symlink : public Node {
public:
Symlink(ino_t id);
virtual ~Symlink();
virtual status_t Init(Directory* parent, const char* name);
virtual status_t AddPackageNode(PackageNode* packageNode);
};
#endif // SYMLINK_H

View File

@ -25,12 +25,11 @@
#include "DebugSupport.h"
#include "Directory.h"
#include "File.h"
#include "LeafNode.h"
#include "kernel_interface.h"
#include "PackageDirectory.h"
#include "PackageFile.h"
#include "PackageSymlink.h"
#include "Symlink.h"
// node ID of the root directory
@ -133,14 +132,30 @@ struct Volume::PackageLoaderContentHandler : PackageContentHandler {
RETURN_ERROR(B_BAD_DATA);
}
status_t error;
// create the package node
PackageNode* node;
if (S_ISREG(entry->Mode())) {
node = new(std::nothrow) PackageFile;
// file
node = new(std::nothrow) PackageFile(entry->Mode(), entry->Data());
} else if (S_ISLNK(entry->Mode())) {
node = new(std::nothrow) PackageSymlink;
// symlink
PackageSymlink* symlink = new(std::nothrow) PackageSymlink(
entry->Mode());
if (symlink == NULL)
RETURN_ERROR(B_NO_MEMORY);
error = symlink->SetSymlinkPath(entry->SymlinkPath());
if (error != B_OK) {
delete symlink;
return error;
}
node = symlink;
} else if (S_ISDIR(entry->Mode())) {
node = new(std::nothrow) PackageDirectory;
// directory
node = new(std::nothrow) PackageDirectory(entry->Mode());
} else
RETURN_ERROR(B_BAD_DATA);
@ -148,12 +163,10 @@ struct Volume::PackageLoaderContentHandler : PackageContentHandler {
RETURN_ERROR(B_NO_MEMORY);
ObjectDeleter<PackageNode> nodeDeleter(node);
status_t error = node->Init(parentDir, entry->Name());
error = node->Init(parentDir, entry->Name());
if (error != B_OK)
RETURN_ERROR(error);
node->SetMode(entry->Mode());
// add it to the parent directory
if (parentDir != NULL)
parentDir->AddChild(node);
@ -579,10 +592,8 @@ Volume::_CreateNode(mode_t mode, Directory* parent, const char* name,
Node*& _node)
{
Node* node;
if (S_ISREG(mode))
node = new(std::nothrow) File(fNextNodeID++);
else if (S_ISLNK(mode))
node = new(std::nothrow) Symlink(fNextNodeID++);
if (S_ISREG(mode) || S_ISLNK(mode))
node = new(std::nothrow) LeafNode(fNextNodeID++);
else if (S_ISDIR(mode))
node = new(std::nothrow) Directory(fNextNodeID++);
else

View File

@ -8,6 +8,7 @@
#include <dirent.h>
#include <algorithm>
#include <new>
#include <fs_info.h>
@ -18,6 +19,7 @@
#include "DebugSupport.h"
#include "Directory.h"
#include "LeafNode.h"
#include "Volume.h"
@ -200,9 +202,30 @@ packagefs_put_vnode(fs_volume* fsVolume, fs_vnode* fsNode, bool reenter)
static status_t
packagefs_read_symlink(fs_volume* fsVolume, fs_vnode* fsNode, char* buffer,
size_t* bufferSize)
size_t* _bufferSize)
{
return B_UNSUPPORTED;
Volume* volume = (Volume*)fsVolume->private_volume;
Node* node = (Node*)fsNode->private_node;
FUNCTION("volume: %p, node: %p (%lld)\n", volume, node, node->ID());
TOUCH(volume);
NodeReadLocker nodeLocker(node);
if (!S_ISLNK(node->Mode()))
return B_BAD_VALUE;
const char* linkPath = dynamic_cast<LeafNode*>(node)->SymlinkPath();
if (linkPath == NULL) {
*_bufferSize = 0;
return B_OK;
}
size_t toCopy = std::min(strlen(linkPath), *_bufferSize);
memcpy(buffer, linkPath, toCopy);
*_bufferSize = toCopy;
return B_OK;
}
@ -211,7 +234,6 @@ packagefs_access(fs_volume* fsVolume, fs_vnode* fsNode, int mode)
{
Volume* volume = (Volume*)fsVolume->private_volume;
Node* node = (Node*)fsNode->private_node;
TOUCH(volume);
FUNCTION("volume: %p, node: %p (%lld)\n", volume, node, node->ID());
TOUCH(volume);
@ -220,6 +242,8 @@ packagefs_access(fs_volume* fsVolume, fs_vnode* fsNode, int mode)
if (mode & W_OK)
return B_READ_ONLY_DEVICE;
NodeReadLocker nodeLocker(node);
// get node permissions
int userPermissions = (node->Mode() & S_IRWXU) >> 6;
int groupPermissions = (node->Mode() & S_IRWXG) >> 3;
@ -259,6 +283,8 @@ packagefs_read_stat(fs_volume* fsVolume, fs_vnode* fsNode, struct stat* st)
FUNCTION("volume: %p, node: %p (%lld)\n", volume, node, node->ID());
TOUCH(volume);
NodeReadLocker nodeLocker(node);
// TODO: Fill in correctly!
st->st_mode = node->Mode();
st->st_nlink = 1;
@ -418,6 +444,7 @@ packagefs_open_dir(fs_volume* fsVolume, fs_vnode* fsNode, void** _cookie)
Directory* dir = dynamic_cast<Directory*>(node);
// create a cookie
NodeWriteLocker dirLocker(dir);
DirectoryCookie* cookie = new(std::nothrow) DirectoryCookie(dir);
if (cookie == NULL)
RETURN_ERROR(B_NO_MEMORY);