mirror of
https://github.com/RGBCube/serenity
synced 2025-05-28 03:35:09 +00:00

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.
97 lines
3.8 KiB
C++
97 lines
3.8 KiB
C++
#pragma once
|
|
|
|
#include <AK/Lock.h>
|
|
#include <AK/Types.h>
|
|
#include <Kernel/FileSystem.h>
|
|
|
|
class Process;
|
|
|
|
class ProcFSInode;
|
|
|
|
class ProcFS final : public FS {
|
|
friend class ProcFSInode;
|
|
public:
|
|
[[gnu::pure]] static ProcFS& the();
|
|
|
|
virtual ~ProcFS() override;
|
|
static Retained<ProcFS> create();
|
|
|
|
virtual bool initialize() override;
|
|
virtual const char* class_name() const override;
|
|
|
|
virtual InodeIdentifier root_inode() const override;
|
|
virtual RetainPtr<Inode> get_inode(InodeIdentifier) const override;
|
|
|
|
virtual RetainPtr<Inode> create_inode(InodeIdentifier parent_id, const String& name, mode_t, unsigned size, int& error) override;
|
|
virtual RetainPtr<Inode> create_directory(InodeIdentifier parent_id, const String& name, mode_t, int& error) override;
|
|
|
|
void add_sys_file(String&&, Function<ByteBuffer(ProcFSInode&)>&& read_callback, Function<ssize_t(ProcFSInode&, const ByteBuffer&)>&& write_callback);
|
|
void add_sys_bool(String&&, Lockable<bool>&, Function<void()>&& notify_callback = nullptr);
|
|
void add_sys_string(String&&, Lockable<String>&, Function<void()>&& notify_callback = nullptr);
|
|
|
|
private:
|
|
ProcFS();
|
|
|
|
struct ProcFSDirectoryEntry {
|
|
ProcFSDirectoryEntry() { }
|
|
ProcFSDirectoryEntry(const char* a_name, unsigned a_proc_file_type, Function<ByteBuffer(InodeIdentifier)>&& a_read_callback = nullptr, Function<ssize_t(InodeIdentifier, const ByteBuffer&)>&& a_write_callback = nullptr, RetainPtr<ProcFSInode>&& a_inode = nullptr)
|
|
: name(a_name)
|
|
, proc_file_type(a_proc_file_type)
|
|
, read_callback(move(a_read_callback))
|
|
, write_callback(move(a_write_callback))
|
|
, inode(move(a_inode))
|
|
{
|
|
}
|
|
|
|
const char* name { nullptr };
|
|
unsigned proc_file_type { 0 };
|
|
Function<ByteBuffer(InodeIdentifier)> read_callback;
|
|
Function<ssize_t(InodeIdentifier, const ByteBuffer&)> write_callback;
|
|
RetainPtr<ProcFSInode> inode;
|
|
InodeIdentifier identifier(unsigned fsid) const;
|
|
};
|
|
|
|
ProcFSDirectoryEntry* get_directory_entry(InodeIdentifier) const;
|
|
|
|
Vector<ProcFSDirectoryEntry> m_entries;
|
|
Vector<ProcFSDirectoryEntry> m_sys_entries;
|
|
|
|
mutable Lock m_inodes_lock;
|
|
mutable HashMap<unsigned, ProcFSInode*> m_inodes;
|
|
RetainPtr<ProcFSInode> m_root_inode;
|
|
};
|
|
|
|
struct ProcFSInodeCustomData {
|
|
virtual ~ProcFSInodeCustomData();
|
|
};
|
|
|
|
class ProcFSInode final : public Inode {
|
|
friend class ProcFS;
|
|
public:
|
|
virtual ~ProcFSInode() override;
|
|
|
|
void set_custom_data(OwnPtr<ProcFSInodeCustomData>&& custom_data) { m_custom_data = move(custom_data); }
|
|
ProcFSInodeCustomData* custom_data() { return m_custom_data.ptr(); }
|
|
const ProcFSInodeCustomData* 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;
|
|
|
|
ProcFS& fs() { return static_cast<ProcFS&>(Inode::fs()); }
|
|
const ProcFS& fs() const { return static_cast<const ProcFS&>(Inode::fs()); }
|
|
ProcFSInode(ProcFS&, unsigned index);
|
|
|
|
OwnPtr<ProcFSInodeCustomData> m_custom_data;
|
|
};
|