#pragma once #include "fs/VFS.h" #include "fs/devices/SlavePTY.h" #include <bits/termios.h> #include <luna/Buffer.h> class MasterPTY : public VFS::DeviceInode { public: MasterPTY() = default; static Result<SharedPtr<VFS::Inode>> create_pair(int index); VFS::InodeType type() const override { return VFS::InodeType::CharacterDevice; } Result<u64> query_shared_memory(off_t, usize) override { return err(ENOTSUP); } VFS::FileSystem* fs() const override { return nullptr; } Result<usize> read(u8* buf, usize offset, usize length) const override; Result<usize> write(const u8* buf, usize offset, usize length) override; Result<u64> ioctl(int request, void* arg) override; Result<u64> isatty() const override { return 1; } Result<void> truncate(usize) override { // POSIX says truncate is for regular files, but doesn't tell us what error to return for non-regular files. return err(EINVAL); } bool will_block_if_read() const override { return m_buffer.is_empty(); } void did_link() override { m_metadata.nlinks++; } void did_unlink() override { m_metadata.nlinks--; } virtual ~MasterPTY(); private: struct termios m_settings; mutable Buffer m_buffer; SharedPtr<SlavePTY> m_slave; mutable Option<pid_t> m_foreground_process_group; struct winsize m_window; Result<void> handle_background_process_group(bool can_succeed, int signo) const; int m_index; friend class SlavePTY; };