#include "fs/Pipe.h" #include "thread/Scheduler.h" Result<void> Pipe::create(SharedPtr<VFS::Inode>& rpipe, SharedPtr<VFS::Inode>& wpipe) { auto pipe = TRY(make_shared<Pipe>()); auto writer = TRY(make_shared<PipeWriter>()); auto reader = TRY(make_shared<PipeReader>()); auto auth = Scheduler::current()->auth; pipe->m_writer = writer.ptr(); pipe->m_reader = reader.ptr(); writer->m_pipe = reader->m_pipe = pipe; writer->m_metadata.inum = 0; writer->m_metadata.uid = auth.euid; writer->m_metadata.gid = auth.egid; writer->m_metadata.mode = 0200; reader->m_metadata.inum = 0; reader->m_metadata.uid = auth.euid; reader->m_metadata.gid = auth.egid; reader->m_metadata.mode = 0400; rpipe = reader; wpipe = writer; return {}; } Result<usize> Pipe::read(u8* buf, usize, usize length) { if (length > m_data_buffer.size()) length = m_data_buffer.size(); memcpy(buf, m_data_buffer.data(), length); memmove(m_data_buffer.data(), m_data_buffer.data() + length, m_data_buffer.size() - length); TRY(m_data_buffer.try_resize(m_data_buffer.size() - length)); return length; } Result<usize> Pipe::write(const u8* buf, usize, usize length) { if (!m_reader) { Scheduler::current()->send_signal(SIGPIPE); return err(EPIPE); } u8* slice = TRY(m_data_buffer.slice_at_end(length)); memcpy(slice, buf, length); return length; } bool Pipe::will_block_if_read() const { return !m_data_buffer.size() && m_writer; } PipeWriter::~PipeWriter() { m_pipe->m_writer = nullptr; } PipeReader::~PipeReader() { m_pipe->m_reader = nullptr; }