libroot_build.so:

* Reorganized sources a bit:
  - The descriptor support is in a separate file now.
  - Disentangled the attribute support from the other stuff.
* Removed broken xattr use for attribute support.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@20606 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ingo Weinhold
2007-04-07 19:01:21 +00:00
parent ea3f7d3d8d
commit a9bf6ecbab
7 changed files with 572 additions and 543 deletions
+1
View File
@@ -26,6 +26,7 @@ BuildPlatformSharedLibrary libroot_build.so :
errors.cpp
fs.cpp
fs_attr.cpp
fs_descriptors.cpp
misc.cpp
sem.cpp
thread.cpp
+7 -399
View File
@@ -1,6 +1,8 @@
#include <BeOSBuildCompatibility.h>
#include "fs_impl.h"
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
@@ -17,296 +19,21 @@
#include <NodeMonitor.h> // for B_STAT_* flags
#include <syscalls.h>
#include "fs_attr_impl.h"
#include "fs_descriptors.h"
#include "NodeRef.h"
using namespace std;
using namespace BPrivate;
static const int kVirtualDescriptorStart = 10000;
static status_t get_path(dev_t device, ino_t node, const char *name, string &path);
static status_t get_path(dev_t device, ino_t node, const char *name,
string &path);
namespace BPrivate {
class Descriptor;
}
using namespace BPrivate;
typedef map<int, Descriptor*> DescriptorMap;
static DescriptorMap sDescriptors;
namespace BPrivate {
// Descriptor
struct Descriptor {
int fd;
virtual ~Descriptor()
{
}
virtual status_t Close() = 0;
virtual status_t Dup(Descriptor *&clone) = 0;
virtual status_t GetStat(bool traverseLink, struct stat *st) = 0;
virtual status_t GetNodeRef(NodeRef &ref)
{
struct stat st;
status_t error = GetStat(false, &st);
if (error != B_OK)
return error;
ref = NodeRef(st);
return B_OK;
}
};
// FileDescriptor
struct FileDescriptor : Descriptor {
FileDescriptor(int fd)
{
this->fd = fd;
}
virtual ~FileDescriptor()
{
Close();
}
virtual status_t Close()
{
if (fd >= 0) {
int oldFD = fd;
fd = -1;
if (close(oldFD) < 0)
return errno;
}
return B_OK;
}
virtual status_t Dup(Descriptor *&clone)
{
int dupFD = dup(fd);
if (dupFD < 0)
return errno;
clone = new FileDescriptor(dupFD);
return B_OK;
}
virtual status_t GetStat(bool traverseLink, struct stat *st)
{
if (fstat(fd, st) < 0)
return errno;
return B_OK;
}
};
// DirectoryDescriptor
struct DirectoryDescriptor : Descriptor {
DIR *dir;
NodeRef ref;
DirectoryDescriptor(DIR *dir, const NodeRef &ref)
{
this->dir = dir;
this->ref = ref;
}
virtual ~DirectoryDescriptor()
{
Close();
}
virtual status_t Close()
{
if (dir) {
DIR *oldDir = dir;
dir = NULL;
if (closedir(oldDir) < 0)
return errno;
}
return B_OK;
}
virtual status_t Dup(Descriptor *&clone)
{
string path;
status_t error = get_path(fd, NULL, path);
if (error != B_OK)
return error;
DIR *dupDir = opendir(path.c_str());
if (!dupDir)
return errno;
clone = new DirectoryDescriptor(dupDir, ref);
return B_OK;
}
virtual status_t GetStat(bool traverseLink, struct stat *st)
{
// get a usable path
string realPath;
status_t error = get_path(fd, NULL, realPath);
if (error != B_OK)
return error;
// stat
int result;
result = stat(realPath.c_str(), st);
if (result < 0)
return errno;
return B_OK;
}
virtual status_t GetNodeRef(NodeRef &ref)
{
ref = this->ref;
return B_OK;
}
};
// SymlinkDescriptor
struct SymlinkDescriptor : Descriptor {
string path;
SymlinkDescriptor(const char *path)
{
this->path = path;
}
virtual status_t Close()
{
return B_OK;
}
virtual status_t Dup(Descriptor *&clone)
{
clone = new SymlinkDescriptor(path.c_str());
return B_OK;
}
virtual status_t GetStat(bool traverseLink, struct stat *st)
{
// stat
int result;
if (traverseLink)
result = stat(path.c_str(), st);
else
result = lstat(path.c_str(), st);
if (result < 0)
return errno;
return B_OK;
}
};
// AttrDirDescriptor
struct AttrDirDescriptor : DirectoryDescriptor {
AttrDirDescriptor(DIR *dir, const NodeRef &ref)
: DirectoryDescriptor(dir, ref)
{
}
virtual ~AttrDirDescriptor()
{
Close();
}
virtual status_t Close()
{
if (dir) {
DIR *oldDir = dir;
dir = NULL;
if (fs_close_attr_dir(oldDir) < 0)
return errno;
}
return B_OK;
}
virtual status_t Dup(Descriptor *&clone)
{
// we don't allow dup()int attr dir descriptors
return B_FILE_ERROR;
}
virtual status_t GetStat(bool traverseLink, struct stat *st)
{
// we don't allow stat()int attr dir descriptors
return B_FILE_ERROR;
}
virtual status_t GetNodeRef(NodeRef &ref)
{
ref = this->ref;
return B_OK;
}
};
} // namespace BPrivate
// get_descriptor
static Descriptor *
get_descriptor(int fd)
{
DescriptorMap::iterator it = sDescriptors.find(fd);
if (it == sDescriptors.end())
return NULL;
return it->second;
}
static int
add_descriptor(Descriptor *descriptor)
{
int fd = -1;
if (FileDescriptor *file = dynamic_cast<FileDescriptor*>(descriptor)) {
fd = file->fd;
} else {
// find a free slot
for (fd = kVirtualDescriptorStart;
sDescriptors.find(fd) != sDescriptors.end();
fd++) {
}
}
sDescriptors[fd] = descriptor;
descriptor->fd = fd;
return fd;
}
// delete_descriptor
static status_t
delete_descriptor(int fd)
{
DescriptorMap::iterator it = sDescriptors.find(fd);
if (it == sDescriptors.end())
return B_FILE_ERROR;
status_t error = it->second->Close();
delete it->second;
sDescriptors.erase(it);
return error;
}
// #pragma mark -
// find_dir_entry
static status_t
find_dir_entry(DIR *dir, const char *path, NodeRef ref, string &name, bool skipDot)
find_dir_entry(DIR *dir, const char *path, NodeRef ref, string &name,
bool skipDot)
{
// find the entry
bool found = false;
@@ -1193,125 +920,6 @@ _kern_unlock_node(int fd)
}
// #pragma mark -
// _kern_open_attr_dir
int
_kern_open_attr_dir(int fd, const char *path)
{
// get node ref for the node
struct stat st;
status_t error = _kern_read_stat(fd, path, false, &st,
sizeof(struct stat));
if (error != B_OK) {
errno = error;
return -1;
}
NodeRef ref(st);
// If a path was given, get a usable path.
string realPath;
if (path) {
error = get_path(fd, path, realPath);
if (error != B_OK)
return error;
}
// open the attr dir
DIR *dir = open_attr_dir(ref, (path ? realPath.c_str() : NULL),
(path ? -1 : fd));
if (!dir)
return errno;
// create descriptor
AttrDirDescriptor *descriptor = new AttrDirDescriptor(dir, ref);
return add_descriptor(descriptor);
}
// get_attribute_path
static status_t
get_attribute_path(int fd, const char *attribute, string &attrPath,
string &typePath)
{
// stat the file to get a NodeRef
struct stat st;
status_t error = _kern_read_stat(fd, NULL, false, &st, sizeof(st));
if (error != B_OK)
return error;
NodeRef ref(st);
// Try to get a path. If we can't get a path, this is must be a "real"
// (i.e. system) file descriptor, which is just as well.
string path;
bool pathValid = (get_path(fd, NULL, path) == B_OK);
// get the attribute path
return get_attribute_path(ref, (pathValid ? path.c_str() : NULL),
(pathValid ? -1 : fd), attribute, attrPath, typePath);
}
// _kern_rename_attr
status_t
_kern_rename_attr(int fromFile, const char *fromName, int toFile,
const char *toName)
{
if (!fromName || !toName)
return B_BAD_VALUE;
// get the attribute paths
string fromAttrPath;
string fromTypePath;
status_t error = get_attribute_path(fromFile, fromName, fromAttrPath,
fromTypePath);
if (error != B_OK)
return error;
string toAttrPath;
string toTypePath;
error = get_attribute_path(toFile, toName, toAttrPath, toTypePath);
if (error != B_OK)
return error;
// rename the attribute and type files
if (rename(fromAttrPath.c_str(), toAttrPath.c_str()) < 0)
return errno;
if (rename(fromTypePath.c_str(), toTypePath.c_str()) < 0) {
// renaming the type file failed: try to rename back the attribute file
error = errno;
rename(toAttrPath.c_str(), fromAttrPath.c_str());
return error;
}
return B_OK;
}
// _kern_remove_attr
status_t
_kern_remove_attr(int fd, const char *name)
{
if (!name)
return B_BAD_VALUE;
// get the attribute path
string attrPath;
string typePath;
status_t error = get_attribute_path(fd, name, attrPath, typePath);
if (error != B_OK)
return error;
// remove the attribute
if (unlink(attrPath.c_str()) < 0)
return errno;
unlink(typePath.c_str());
return B_OK;
}
// #pragma mark -
// read_pos
+142 -116
View File
@@ -9,11 +9,6 @@
# include <syscalls.h>
#endif
// Defined, if the host platform has extended attribute support.
// Unfortunately I don't seem to have extended attribute support under
// SuSE Linux 9.2 (kernel 2.6.8-...) with ReiserFS 3.6.
//#define HAS_EXTENDED_ATTRIBUTE_SUPPORT 1
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
@@ -26,13 +21,9 @@
#include <fs_attr.h>
#include "fs_attr_impl.h"
#include "fs_impl.h"
#include "fs_descriptors.h"
#ifdef HAS_EXTENDED_ATTRIBUTE_SUPPORT
#include <sys/xattr.h>
static const char *kAttributeDirMarkAttributeName = "_has_haiku_attr_dir";
#endif
using namespace std;
using namespace BPrivate;
@@ -133,87 +124,6 @@ get_attribute_dir_path(NodeRef ref)
return attrDirPath;
}
// has_attribute_dir_mark
static bool
has_attribute_dir_mark(const char *path, int fd)
{
#ifdef HAS_EXTENDED_ATTRIBUTE_SUPPORT
uint8 value;
if (path) {
return (lgetxattr(path, kAttributeDirMarkAttributeName, &value, 1)
> 0);
} else {
return (fgetxattr(fd, kAttributeDirMarkAttributeName, &value, 1)
> 0);
}
#else // !HAS_EXTENDED_ATTRIBUTE_SUPPORT
// No extended attribute support. We can't mark the file and thus
// have to handle it as marked.
return true;
#endif
}
// set_attribute_dir_mark
static status_t
set_attribute_dir_mark(const char *path, int fd)
{
#ifdef HAS_EXTENDED_ATTRIBUTE_SUPPORT
uint8 value = 1;
if (path) {
if (lsetxattr(path, kAttributeDirMarkAttributeName, &value, 1, 0)
< 0) {
fprintf(stderr, "set_attribute_dir_mark(): lsetxattr() "
"failed on \"%s\"\n", path);
return errno;
}
} else {
if (fsetxattr(fd, kAttributeDirMarkAttributeName, &value, 1, 0)
< 0) {
fprintf(stderr, "set_attribute_dir_mark(): fsetxattr() "
"failed on FD \"%d\"\n", fd);
return errno;
}
}
#endif
return B_OK;
}
// empty_attribute_dir
static status_t
empty_attribute_dir(const char *path)
{
DIR *dir = opendir(path);
if (!dir)
return errno;
while (dirent *entry = readdir(dir)) {
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)
continue;
string entryPath(path);
entryPath += '/';
entryPath += entry->d_name;
// We assume the attribute dir contains files only (we only create
// files) and thus use unlink().
if (unlink(entryPath.c_str()) < 0) {
status_t error = errno;
closedir(dir);
return error;
}
}
closedir(dir);
return B_OK;
}
// ensure_attribute_dir_exists
static status_t
ensure_attribute_dir_exists(NodeRef ref, const char *path, int fd)
@@ -235,37 +145,19 @@ ensure_attribute_dir_exists(NodeRef ref, const char *path, int fd)
return B_FILE_ERROR;
}
// already exists: Check whether the file is marked. If not, this
// is a stale attribute directory from a deleted node that had the
// same node ID as this one.
if (has_attribute_dir_mark(path, fd))
return B_OK;
// empty the attribute dir
error = empty_attribute_dir(attrDirPath.c_str());
if (error != B_OK) {
fprintf(stderr, "ensure_attribute_dir_exists(): Attribute "
"directory for node %lld exists, the node has no mark, and "
"emptying the attribute directory failed\n",
ref.node);
return error;
}
// mark the file
return set_attribute_dir_mark(path, fd);
return B_OK;
}
// doesn't exist yet: create it
if (mkdir(attrDirPath.c_str(), S_IRWXU | S_IRWXG | S_IRWXO) < 0)
return errno;
// mark the file
return set_attribute_dir_mark(path, fd);
return B_OK;
}
// open_attr_dir
DIR *
BPrivate::open_attr_dir(NodeRef ref, const char *path, int fd)
static DIR *
open_attr_dir(NodeRef ref, const char *path, int fd)
{
// make sure the directory exists
status_t error = ensure_attribute_dir_exists(ref, path, fd);
@@ -280,8 +172,8 @@ BPrivate::open_attr_dir(NodeRef ref, const char *path, int fd)
}
// get_attribute_path
status_t
BPrivate::get_attribute_path(NodeRef ref, const char *path, int fd,
static status_t
get_attribute_path(NodeRef ref, const char *path, int fd,
const char *attribute, string &attrPath, string &typePath)
{
if (!attribute || strlen(attribute) == 0)
@@ -317,6 +209,37 @@ get_attribute_path(int fd, const char *attribute, string &attrPath,
return get_attribute_path(ref, NULL, fd, attribute, attrPath, typePath);
}
#ifndef BUILDING_FS_SHELL
// get_attribute_path_virtual_fd
static status_t
get_attribute_path_virtual_fd(int fd, const char *attribute, string &attrPath,
string &typePath)
{
// stat the file to get a NodeRef
struct stat st;
status_t error = _kern_read_stat(fd, NULL, false, &st, sizeof(st));
if (error != B_OK)
return error;
NodeRef ref(st);
// Try to get a path. If we can't get a path, this is must be a "real"
// (i.e. system) file descriptor, which is just as well.
string path;
bool pathValid = (get_path(fd, NULL, path) == B_OK);
// get the attribute path
return get_attribute_path(ref, (pathValid ? path.c_str() : NULL),
(pathValid ? -1 : fd), attribute, attrPath, typePath);
}
#endif // ! BUILDING_FS_SHELL
// # pragma mark - Public API
// fs_open_attr_dir
DIR *
fs_open_attr_dir(const char *path)
@@ -586,3 +509,106 @@ fs_stat_attr(int fd, const char *attribute, struct attr_info *attrInfo)
return 0;
}
// #pragma mark - Private Syscalls
#ifndef BUILDING_FS_SHELL
// _kern_open_attr_dir
int
_kern_open_attr_dir(int fd, const char *path)
{
// get node ref for the node
struct stat st;
status_t error = _kern_read_stat(fd, path, false, &st,
sizeof(struct stat));
if (error != B_OK) {
errno = error;
return -1;
}
NodeRef ref(st);
// If a path was given, get a usable path.
string realPath;
if (path) {
error = get_path(fd, path, realPath);
if (error != B_OK)
return error;
}
// open the attr dir
DIR *dir = open_attr_dir(ref, (path ? realPath.c_str() : NULL),
(path ? -1 : fd));
if (!dir)
return errno;
// create descriptor
AttrDirDescriptor *descriptor = new AttrDirDescriptor(dir, ref);
return add_descriptor(descriptor);
}
// _kern_rename_attr
status_t
_kern_rename_attr(int fromFile, const char *fromName, int toFile,
const char *toName)
{
if (!fromName || !toName)
return B_BAD_VALUE;
// get the attribute paths
string fromAttrPath;
string fromTypePath;
status_t error = get_attribute_path_virtual_fd(fromFile, fromName,
fromAttrPath, fromTypePath);
if (error != B_OK)
return error;
string toAttrPath;
string toTypePath;
error = get_attribute_path_virtual_fd(toFile, toName, toAttrPath,
toTypePath);
if (error != B_OK)
return error;
// rename the attribute and type files
if (rename(fromAttrPath.c_str(), toAttrPath.c_str()) < 0)
return errno;
if (rename(fromTypePath.c_str(), toTypePath.c_str()) < 0) {
// renaming the type file failed: try to rename back the attribute file
error = errno;
rename(toAttrPath.c_str(), fromAttrPath.c_str());
return error;
}
return B_OK;
}
// _kern_remove_attr
status_t
_kern_remove_attr(int fd, const char *name)
{
if (!name)
return B_BAD_VALUE;
// get the attribute path
string attrPath;
string typePath;
status_t error = get_attribute_path_virtual_fd(fd, name, attrPath,
typePath);
if (error != B_OK)
return error;
// remove the attribute
if (unlink(attrPath.c_str()) < 0)
return errno;
unlink(typePath.c_str());
return B_OK;
}
#endif // ! BUILDING_FS_SHELL
-28
View File
@@ -1,28 +0,0 @@
#ifndef FS_ATTR_IMPL_H
#define FS_ATTR_IMPL_H
#include <dirent.h>
#include <string>
#include "NodeRef.h"
namespace BPrivate {
// defined in fs_attr.cpp
// Note: Only one of path or fd can be supplied.
DIR *open_attr_dir(NodeRef ref, const char *path, int fd);
// Note: Only one of path or fd can be supplied.
status_t get_attribute_path(NodeRef ref, const char *path, int fd,
const char *attribute, std::string &attrPath, std::string &typePath);
// defined in fs.cpp
status_t get_path(int fd, const char *name, std::string &path);
} // namespace BPrivate
#endif // FS_ATTR_IMPL_H
+319
View File
@@ -0,0 +1,319 @@
#include <BeOSBuildCompatibility.h>
#include "fs_descriptors.h"
#include <map>
#include <stdio.h>
#include <unistd.h>
#include <fs_attr.h>
#include "fs_impl.h"
using std::map;
static const int kVirtualDescriptorStart = 10000;
typedef map<int, BPrivate::Descriptor*> DescriptorMap;
static DescriptorMap sDescriptors;
namespace BPrivate {
// #pragma mark - Descriptor
// constructor
Descriptor::~Descriptor()
{
}
// GetNodeRef
status_t
Descriptor::GetNodeRef(NodeRef &ref)
{
struct stat st;
status_t error = GetStat(false, &st);
if (error != B_OK)
return error;
ref = NodeRef(st);
return B_OK;
}
// #pragma mark - FileDescriptor
// constructor
FileDescriptor::FileDescriptor(int fd)
{
this->fd = fd;
}
// destructor
FileDescriptor::~FileDescriptor()
{
Close();
}
// Close
status_t
FileDescriptor::Close()
{
if (fd >= 0) {
int oldFD = fd;
fd = -1;
if (close(oldFD) < 0)
return errno;
}
return B_OK;
}
// Dup
status_t
FileDescriptor::Dup(Descriptor *&clone)
{
int dupFD = dup(fd);
if (dupFD < 0)
return errno;
clone = new FileDescriptor(dupFD);
return B_OK;
}
// GetStat
status_t
FileDescriptor::GetStat(bool traverseLink, struct stat *st)
{
if (fstat(fd, st) < 0)
return errno;
return B_OK;
}
// #pragma mark - DirectoryDescriptor
// constructor
DirectoryDescriptor::DirectoryDescriptor(DIR *dir, const NodeRef &ref)
{
this->dir = dir;
this->ref = ref;
}
// destructor
DirectoryDescriptor::~DirectoryDescriptor()
{
Close();
}
// Close
status_t
DirectoryDescriptor::Close()
{
if (dir) {
DIR *oldDir = dir;
dir = NULL;
if (closedir(oldDir) < 0)
return errno;
}
return B_OK;
}
// Dup
status_t
DirectoryDescriptor::Dup(Descriptor *&clone)
{
string path;
status_t error = get_path(fd, NULL, path);
if (error != B_OK)
return error;
DIR *dupDir = opendir(path.c_str());
if (!dupDir)
return errno;
clone = new DirectoryDescriptor(dupDir, ref);
return B_OK;
}
// GetStat
status_t
DirectoryDescriptor::GetStat(bool traverseLink, struct stat *st)
{
// get a usable path
string realPath;
status_t error = get_path(fd, NULL, realPath);
if (error != B_OK)
return error;
// stat
int result;
result = stat(realPath.c_str(), st);
if (result < 0)
return errno;
return B_OK;
}
// GetNodeRef
status_t
DirectoryDescriptor::GetNodeRef(NodeRef &ref)
{
ref = this->ref;
return B_OK;
}
// #pragma mark - SymlinkDescriptor
// constructor
SymlinkDescriptor::SymlinkDescriptor(const char *path)
{
this->path = path;
}
// Close
status_t
SymlinkDescriptor::Close()
{
return B_OK;
}
// Dup
status_t
SymlinkDescriptor::Dup(Descriptor *&clone)
{
clone = new SymlinkDescriptor(path.c_str());
return B_OK;
}
// GetStat
status_t
SymlinkDescriptor::GetStat(bool traverseLink, struct stat *st)
{
// stat
int result;
if (traverseLink)
result = stat(path.c_str(), st);
else
result = lstat(path.c_str(), st);
if (result < 0)
return errno;
return B_OK;
}
// #pragma mark - AttrDirDescriptor
// constructor
AttrDirDescriptor::AttrDirDescriptor(DIR *dir, const NodeRef &ref)
: DirectoryDescriptor(dir, ref)
{
}
// destructor
AttrDirDescriptor::~AttrDirDescriptor()
{
Close();
}
// Close
status_t
AttrDirDescriptor::Close()
{
if (dir) {
DIR *oldDir = dir;
dir = NULL;
if (fs_close_attr_dir(oldDir) < 0)
return errno;
}
return B_OK;
}
// Dup
status_t
AttrDirDescriptor::Dup(Descriptor *&clone)
{
// we don't allow dup()int attr dir descriptors
return B_FILE_ERROR;
}
// GetStat
status_t
AttrDirDescriptor::GetStat(bool traverseLink, struct stat *st)
{
// we don't allow stat()int attr dir descriptors
return B_FILE_ERROR;
}
// GetNodeRef
status_t
AttrDirDescriptor::GetNodeRef(NodeRef &ref)
{
ref = this->ref;
return B_OK;
}
// get_descriptor
Descriptor *
get_descriptor(int fd)
{
DescriptorMap::iterator it = sDescriptors.find(fd);
if (it == sDescriptors.end())
return NULL;
return it->second;
}
// add_descriptor
int
add_descriptor(Descriptor *descriptor)
{
int fd = -1;
if (FileDescriptor *file = dynamic_cast<FileDescriptor*>(descriptor)) {
fd = file->fd;
} else {
// find a free slot
for (fd = kVirtualDescriptorStart;
sDescriptors.find(fd) != sDescriptors.end();
fd++) {
}
}
sDescriptors[fd] = descriptor;
descriptor->fd = fd;
return fd;
}
// delete_descriptor
status_t
delete_descriptor(int fd)
{
DescriptorMap::iterator it = sDescriptors.find(fd);
if (it == sDescriptors.end())
return B_FILE_ERROR;
status_t error = it->second->Close();
delete it->second;
sDescriptors.erase(it);
return error;
}
} // namespace BPrivate
+87
View File
@@ -0,0 +1,87 @@
#ifndef FS_DESCRIPTORS_H
#define FS_DESCRIPTORS_H
#include <dirent.h>
#include <string>
#include <SupportDefs.h>
#include "NodeRef.h"
using std::string;
struct stat;
namespace BPrivate {
// Descriptor
struct Descriptor {
int fd;
virtual ~Descriptor();
virtual status_t Close() = 0;
virtual status_t Dup(Descriptor *&clone) = 0;
virtual status_t GetStat(bool traverseLink, struct stat *st) = 0;
virtual status_t GetNodeRef(NodeRef &ref);
};
// FileDescriptor
struct FileDescriptor : Descriptor {
FileDescriptor(int fd);
virtual ~FileDescriptor();
virtual status_t Close();
virtual status_t Dup(Descriptor *&clone);
virtual status_t GetStat(bool traverseLink, struct stat *st);
};
// DirectoryDescriptor
struct DirectoryDescriptor : Descriptor {
DIR *dir;
NodeRef ref;
DirectoryDescriptor(DIR *dir, const NodeRef &ref);
virtual ~DirectoryDescriptor();
virtual status_t Close();
virtual status_t Dup(Descriptor *&clone);
virtual status_t GetStat(bool traverseLink, struct stat *st);
virtual status_t GetNodeRef(NodeRef &ref);
};
// SymlinkDescriptor
struct SymlinkDescriptor : Descriptor {
string path;
SymlinkDescriptor(const char *path);
virtual status_t Close();
virtual status_t Dup(Descriptor *&clone);
virtual status_t GetStat(bool traverseLink, struct stat *st);
};
// AttrDirDescriptor
struct AttrDirDescriptor : DirectoryDescriptor {
AttrDirDescriptor(DIR *dir, const NodeRef &ref);
virtual ~AttrDirDescriptor();
virtual status_t Close();
virtual status_t Dup(Descriptor *&clone);
virtual status_t GetStat(bool traverseLink, struct stat *st);
virtual status_t GetNodeRef(NodeRef &ref);
};
Descriptor* get_descriptor(int fd);
int add_descriptor(Descriptor *descriptor);
status_t delete_descriptor(int fd);
} // namespace BPrivate
#endif // FS_DESCRIPTORS_H
+16
View File
@@ -0,0 +1,16 @@
#ifndef FS_IMPL_H
#define FS_IMPL_H
#include <string>
#include <SupportDefs.h>
namespace BPrivate {
// defined in fs.cpp
status_t get_path(int fd, const char *name, std::string &path);
} // namespace BPrivate
#endif // FS_IMPL_H