1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-30 23:08:11 +00:00
serenity/Kernel/SyntheticFileSystem.h
Andreas Kling 5af4e622b9 Kernel: Add KResult and KResultOr<T> classes.
The idea here is to combine a potential syscall error code with an arbitrary
type in the case of success. I feel like this will end up much less error
prone than returning some arbitrary type that kinda sorta has bool semantics
(but sometimes not really) and passing the error through an out-param.

This patch only converts a few syscalls to using it. More to come.
2019-02-25 20:50:22 +01:00

94 lines
3.5 KiB
C++

#pragma once
#include "FileSystem.h"
#include "UnixTypes.h"
#include <AK/HashMap.h>
class SynthFSInode;
class SynthFS : public FS {
public:
virtual ~SynthFS() override;
static Retained<SynthFS> create();
virtual bool initialize() override;
virtual const char* class_name() const override;
virtual InodeIdentifier root_inode() const override;
virtual RetainPtr<Inode> create_inode(InodeIdentifier parentInode, const String& name, mode_t, unsigned size, int& error) override;
virtual RetainPtr<Inode> create_directory(InodeIdentifier parentInode, const String& name, mode_t, int& error) override;
virtual RetainPtr<Inode> get_inode(InodeIdentifier) const override;
protected:
typedef unsigned InodeIndex;
InodeIndex generate_inode_index();
static constexpr InodeIndex RootInodeIndex = 1;
SynthFS();
Retained<SynthFSInode> create_directory(String&& name);
Retained<SynthFSInode> create_text_file(String&& name, ByteBuffer&&, mode_t = 0010644);
Retained<SynthFSInode> create_generated_file(String&& name, Function<ByteBuffer(SynthFSInode&)>&&, mode_t = 0100644);
Retained<SynthFSInode> create_generated_file(String&& name, Function<ByteBuffer(SynthFSInode&)>&&, Function<ssize_t(SynthFSInode&, const ByteBuffer&)>&&, mode_t = 0100644);
InodeIdentifier add_file(RetainPtr<SynthFSInode>&&, InodeIndex parent = RootInodeIndex);
bool remove_file(InodeIndex);
private:
InodeIndex m_next_inode_index { 2 };
HashMap<InodeIndex, RetainPtr<SynthFSInode>> m_inodes;
mutable Lock m_lock;
};
struct SynthFSInodeCustomData {
virtual ~SynthFSInodeCustomData();
};
class SynthFSInode final : public Inode {
friend class SynthFS;
friend class DevPtsFS;
public:
virtual ~SynthFSInode() override;
void set_custom_data(OwnPtr<SynthFSInodeCustomData>&& custom_data) { m_custom_data = move(custom_data); }
SynthFSInodeCustomData* custom_data() { return m_custom_data.ptr(); }
const SynthFSInodeCustomData* custom_data() const { return m_custom_data.ptr(); }
private:
// ^Inode
virtual ssize_t read_bytes(off_t, size_t, byte* buffer, FileDescriptor*) const override;
virtual InodeMetadata metadata() const override;
virtual bool traverse_as_directory(Function<bool(const FS::DirectoryEntry&)>) const override;
virtual InodeIdentifier lookup(const String& name) override;
virtual String reverse_lookup(InodeIdentifier) override;
virtual void flush_metadata() override;
virtual ssize_t write_bytes(off_t, size_t, const byte* buffer, FileDescriptor*) override;
virtual bool add_child(InodeIdentifier child_id, const String& name, byte file_type, int& error) override;
virtual bool remove_child(const String& name, int& error) override;
virtual RetainPtr<Inode> parent() const override;
virtual size_t directory_entry_count() const override;
virtual KResult chmod(mode_t) override;
SynthFS& fs();
const SynthFS& fs() const;
SynthFSInode(SynthFS&, unsigned index);
String m_name;
InodeIdentifier m_parent;
ByteBuffer m_data;
Function<ByteBuffer(SynthFSInode&)> m_generator;
Function<ssize_t(SynthFSInode&, const ByteBuffer&)> m_write_callback;
Vector<SynthFSInode*> m_children;
InodeMetadata m_metadata;
OwnPtr<SynthFSInodeCustomData> m_custom_data;
};
inline SynthFS& SynthFSInode::fs()
{
return static_cast<SynthFS&>(Inode::fs());
}
inline const SynthFS& SynthFSInode::fs() const
{
return static_cast<const SynthFS&>(Inode::fs());
}