Luna/kernel/src/fs/Pipe.h
apio 3a51807fa6
All checks were successful
continuous-integration/drone/push Build is passing
kernel+stat: Handle pipes correctly in stat()
2023-05-23 20:54:25 +02:00

140 lines
2.5 KiB
C++

#pragma once
#include "fs/VFS.h"
#include <luna/Buffer.h>
class PipeInodeBase;
class PipeReader;
class PipeWriter;
class Pipe
{
public:
static Result<void> create(SharedPtr<VFS::Inode>& rpipe, SharedPtr<VFS::Inode>& wpipe);
Result<usize> read(u8* buf, usize, usize length);
Result<usize> write(const u8* buf, usize, usize length);
bool blocking() 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<void> truncate(usize) override
{
return err(ENOTSUP);
}
bool blocking() const override
{
return m_pipe->blocking();
}
usize size() const override
{
return m_pipe->m_data_buffer.size();
}
void did_link() override
{
}
void did_unlink() override
{
}
Result<void> chmod(mode_t) override
{
return err(ENOTSUP);
}
Result<void> chown(u32 uid, u32 gid) override
{
m_uid = uid;
m_gid = gid;
return {};
}
usize inode_number() const override
{
return 0;
}
VFS::FileSystem* fs() const override
{
return nullptr;
}
virtual ~PipeInodeBase() = default;
friend class Pipe;
protected:
SharedPtr<Pipe> m_pipe;
u32 m_uid { 0 };
u32 m_gid { 0 };
};
class PipeWriter : public PipeInodeBase
{
public:
Result<usize> read(u8*, usize, usize) const override
{
// A FileDescriptor pointing to a PipeWriter should never be opened for reading.
check(false);
}
Result<usize> write(const u8* buf, usize offset, usize length) override
{
return m_pipe->write(buf, offset, length);
}
mode_t mode() const override
{
return 0200;
}
~PipeWriter();
friend class Pipe;
};
class PipeReader : public PipeInodeBase
{
public:
Result<usize> read(u8* buf, usize offset, usize length) const override
{
return m_pipe->read(buf, offset, length);
}
Result<usize> write(const u8*, usize, usize) override
{
// A FileDescriptor pointing to a PipeReader should never be opened for writing.
check(false);
}
mode_t mode() const override
{
return 0400;
}
~PipeReader();
friend class Pipe;
};