#pragma once #include #include #include namespace Kernel { class ProcPidInode final : public TmpDirectoryInode { // FIXME: dynamically update ruid/rgid. // Possibly just have a magic uid/gid of -1 or something // which means use current process ID public: static BAN::ErrorOr> create_new(Process&, TmpFileSystem&, mode_t); ~ProcPidInode() = default; void cleanup(); protected: virtual BAN::ErrorOr unlink_impl(BAN::StringView) override { return BAN::Error::from_errno(EPERM); } private: ProcPidInode(Process&, TmpFileSystem&, const TmpInodeInfo&); }; class ProcROProcessInode final : public TmpInode { //FIXME: dynamically update ruid/rgid public: static BAN::ErrorOr> create_new(Process&, size_t (Process::*callback)(off_t, BAN::ByteSpan) const, TmpFileSystem&, mode_t); ~ProcROProcessInode() = default; protected: virtual BAN::ErrorOr read_impl(off_t, BAN::ByteSpan) override; // You may not write here and this is always non blocking virtual BAN::ErrorOr write_impl(off_t, BAN::ConstByteSpan) override { return BAN::Error::from_errno(EINVAL); } virtual BAN::ErrorOr truncate_impl(size_t) override { return BAN::Error::from_errno(EINVAL); } virtual bool can_read_impl() const override { return true; } virtual bool can_write_impl() const override { return false; } virtual bool has_error_impl() const override { return false; } virtual bool has_hungup_impl() const override { return false; } private: ProcROProcessInode(Process&, size_t (Process::*)(off_t, BAN::ByteSpan) const, TmpFileSystem&, const TmpInodeInfo&); private: Process& m_process; size_t (Process::*m_callback)(off_t, BAN::ByteSpan) const; }; class ProcSymlinkProcessInode final : public TmpInode { //FIXME: dynamically update ruid/rgid public: static BAN::ErrorOr> create_new(Process& process, BAN::ErrorOr (Process::*callback)() const, TmpFileSystem&, mode_t); ~ProcSymlinkProcessInode() = default; protected: virtual BAN::ErrorOr link_target_impl() override; virtual bool can_read_impl() const override { return false; } virtual bool can_write_impl() const override { return false; } virtual bool has_error_impl() const override { return false; } virtual bool has_hungup_impl() const override { return false; } private: ProcSymlinkProcessInode(Process& process, BAN::ErrorOr (Process::*)() const, TmpFileSystem&, const TmpInodeInfo&); private: Process& m_process; BAN::ErrorOr (Process::*m_callback)() const; }; class ProcROInode final : public TmpInode { public: static BAN::ErrorOr> create_new(BAN::ErrorOr (*callback)(off_t, BAN::ByteSpan, void*), TmpFileSystem&, void*, mode_t, uid_t, gid_t); ~ProcROInode() = default; protected: virtual BAN::ErrorOr read_impl(off_t, BAN::ByteSpan) override; // You may not write here and this is always non blocking virtual BAN::ErrorOr write_impl(off_t, BAN::ConstByteSpan) override { return BAN::Error::from_errno(EINVAL); } virtual BAN::ErrorOr truncate_impl(size_t) override { return BAN::Error::from_errno(EINVAL); } virtual bool can_read_impl() const override { return true; } virtual bool can_write_impl() const override { return false; } virtual bool has_error_impl() const override { return false; } virtual bool has_hungup_impl() const override { return false; } private: ProcROInode(BAN::ErrorOr (*callback)(off_t, BAN::ByteSpan, void*), TmpFileSystem&, void*, const TmpInodeInfo&); private: BAN::ErrorOr (*m_callback)(off_t, BAN::ByteSpan, void*); void* m_argument; }; class ProcSymlinkInode final : public TmpInode { public: static BAN::ErrorOr> create_new(BAN::ErrorOr (*)(void*), void (*)(void*), void* data, TmpFileSystem&, mode_t, uid_t, gid_t); ~ProcSymlinkInode(); protected: virtual BAN::ErrorOr link_target_impl() override; virtual bool can_read_impl() const override { return false; } virtual bool can_write_impl() const override { return false; } virtual bool has_error_impl() const override { return false; } virtual bool has_hungup_impl() const override { return false; } private: ProcSymlinkInode(BAN::ErrorOr (*callback)(void*), void (*destructor)(void*), void* data, TmpFileSystem&, const TmpInodeInfo&); private: BAN::ErrorOr (*m_callback)(void*); void (*m_destructor)(void*); void* m_data; }; class ProcFDDirectoryInode final : public TmpInode { //FIXME: dynamically update ruid/rgid public: static BAN::ErrorOr> create_new(Process&, TmpFileSystem&, mode_t); ~ProcFDDirectoryInode() = default; protected: virtual BAN::ErrorOr> find_inode_impl(BAN::StringView) override; virtual BAN::ErrorOr list_next_inodes_impl(off_t, struct dirent*, size_t) override; virtual BAN::ErrorOr create_file_impl(BAN::StringView, mode_t, uid_t, gid_t) override { return BAN::Error::from_errno(EPERM); } virtual BAN::ErrorOr create_directory_impl(BAN::StringView, mode_t, uid_t, gid_t) override { return BAN::Error::from_errno(EPERM); } virtual BAN::ErrorOr link_inode_impl(BAN::StringView, BAN::RefPtr) override { return BAN::Error::from_errno(EPERM); } virtual BAN::ErrorOr rename_inode_impl(BAN::RefPtr, BAN::StringView, BAN::StringView) override { return BAN::Error::from_errno(EPERM); } virtual BAN::ErrorOr unlink_impl(BAN::StringView) override { return BAN::Error::from_errno(EPERM); } virtual bool can_read_impl() const override { return false; } virtual bool can_write_impl() const override { return false; } virtual bool has_error_impl() const override { return false; } virtual bool has_hungup_impl() const override { return false; } private: ProcFDDirectoryInode(Process&, TmpFileSystem&, const TmpInodeInfo&); private: Process& m_process; }; }