#pragma once #include "fs/VFS.h" #include class PipeInodeBase; class PipeReader; class PipeWriter; class Pipe : public Shareable { public: static Result create(SharedPtr& rpipe, SharedPtr& wpipe); Result read(u8* buf, usize, usize length); Result write(const u8* buf, usize, usize length); bool will_block_if_read() const; private: Buffer m_data_buffer; PipeWriter* m_writer; PipeReader* m_reader; friend class PipeInodeBase; friend class PipeReader; friend class PipeWriter; }; class PipeInodeBase : public VFS::FileInode { public: VFS::InodeType type() const override { return VFS::InodeType::FIFO; } Result truncate(usize) override { return err(ENOTSUP); } bool will_block_if_read() const override { return m_pipe->will_block_if_read(); } const VFS::InodeMetadata& metadata() const override { m_metadata.size = m_pipe->m_data_buffer.size(); return m_metadata; } void did_link() override { } void did_unlink() override { } VFS::FileSystem* fs() const override { return nullptr; } virtual ~PipeInodeBase() = default; friend class Pipe; protected: SharedPtr m_pipe; }; class PipeWriter : public PipeInodeBase { public: Result read(u8*, usize, usize) const override { // A FileDescriptor pointing to a PipeWriter should never be opened for reading. check(false); } Result write(const u8* buf, usize offset, usize length) override { return m_pipe->write(buf, offset, length); } ~PipeWriter(); friend class Pipe; }; class PipeReader : public PipeInodeBase { public: Result read(u8* buf, usize offset, usize length) const override { return m_pipe->read(buf, offset, length); } Result write(const u8*, usize, usize) override { // A FileDescriptor pointing to a PipeReader should never be opened for writing. check(false); } ~PipeReader(); friend class Pipe; };