diff --git a/src/build/libroot/Jamfile b/src/build/libroot/Jamfile index f1df1e9b14..8dfa03842d 100644 --- a/src/build/libroot/Jamfile +++ b/src/build/libroot/Jamfile @@ -26,6 +26,7 @@ BuildPlatformSharedLibrary libroot_build.so : errors.cpp fs.cpp fs_attr.cpp + fs_descriptors.cpp misc.cpp sem.cpp thread.cpp diff --git a/src/build/libroot/fs.cpp b/src/build/libroot/fs.cpp index 7db03caacc..14e2d6c64a 100644 --- a/src/build/libroot/fs.cpp +++ b/src/build/libroot/fs.cpp @@ -1,6 +1,8 @@ #include +#include "fs_impl.h" + #include #include #include @@ -17,296 +19,21 @@ #include // for B_STAT_* flags #include -#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 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(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 diff --git a/src/build/libroot/fs_attr.cpp b/src/build/libroot/fs_attr.cpp index 39bcca1452..4fd1680372 100644 --- a/src/build/libroot/fs_attr.cpp +++ b/src/build/libroot/fs_attr.cpp @@ -9,11 +9,6 @@ # include #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 #include #include @@ -26,13 +21,9 @@ #include -#include "fs_attr_impl.h" +#include "fs_impl.h" +#include "fs_descriptors.h" -#ifdef HAS_EXTENDED_ATTRIBUTE_SUPPORT -#include - -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 diff --git a/src/build/libroot/fs_attr_impl.h b/src/build/libroot/fs_attr_impl.h deleted file mode 100644 index ebf2e2761c..0000000000 --- a/src/build/libroot/fs_attr_impl.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef FS_ATTR_IMPL_H -#define FS_ATTR_IMPL_H - -#include - -#include - -#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 diff --git a/src/build/libroot/fs_descriptors.cpp b/src/build/libroot/fs_descriptors.cpp new file mode 100644 index 0000000000..454b8e16f5 --- /dev/null +++ b/src/build/libroot/fs_descriptors.cpp @@ -0,0 +1,319 @@ + +#include + +#include "fs_descriptors.h" + +#include + +#include +#include + +#include + +#include "fs_impl.h" + +using std::map; + +static const int kVirtualDescriptorStart = 10000; + +typedef map 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(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 diff --git a/src/build/libroot/fs_descriptors.h b/src/build/libroot/fs_descriptors.h new file mode 100644 index 0000000000..cf85ece5ca --- /dev/null +++ b/src/build/libroot/fs_descriptors.h @@ -0,0 +1,87 @@ +#ifndef FS_DESCRIPTORS_H +#define FS_DESCRIPTORS_H + +#include + +#include + +#include + +#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 diff --git a/src/build/libroot/fs_impl.h b/src/build/libroot/fs_impl.h new file mode 100644 index 0000000000..be5efa3fa8 --- /dev/null +++ b/src/build/libroot/fs_impl.h @@ -0,0 +1,16 @@ +#ifndef FS_IMPL_H +#define FS_IMPL_H + +#include + +#include + +namespace BPrivate { + +// defined in fs.cpp + +status_t get_path(int fd, const char *name, std::string &path); + +} // namespace BPrivate + +#endif // FS_IMPL_H