diff --git a/Kernel/TTY/MasterPTY.cpp b/Kernel/TTY/MasterPTY.cpp index 2179d7c90f..dea6557f91 100644 --- a/Kernel/TTY/MasterPTY.cpp +++ b/Kernel/TTY/MasterPTY.cpp @@ -16,17 +16,36 @@ namespace Kernel { -MasterPTY::MasterPTY(unsigned index) +RefPtr MasterPTY::try_create(unsigned int index) +{ + auto buffer = DoubleBuffer::try_create(); + if (!buffer) + return {}; + + auto master_pty = adopt_ref_if_nonnull(new (nothrow) MasterPTY(index, buffer.release_nonnull())); + if (!master_pty) + return {}; + + auto slave_pty = adopt_ref_if_nonnull(new (nothrow) SlavePTY(*master_pty, index)); + if (!slave_pty) + return {}; + + master_pty->m_slave = slave_pty; + + return master_pty; +} + +MasterPTY::MasterPTY(unsigned index, NonnullOwnPtr buffer) : CharacterDevice(200, index) - , m_slave(adopt_ref(*new SlavePTY(*this, index))) , m_index(index) + , m_buffer(move(buffer)) { m_pts_name = String::formatted("/dev/pts/{}", m_index); auto process = Process::current(); set_uid(process->uid()); set_gid(process->gid()); - m_buffer.set_unblock_callback([this]() { + m_buffer->set_unblock_callback([this]() { if (m_slave) evaluate_block_conditions(); }); @@ -45,9 +64,9 @@ String MasterPTY::pts_name() const KResultOr MasterPTY::read(FileDescription&, u64, UserOrKernelBuffer& buffer, size_t size) { - if (!m_slave && m_buffer.is_empty()) + if (!m_slave && m_buffer->is_empty()) return 0; - return m_buffer.read(buffer, size); + return m_buffer->read(buffer, size); } KResultOr MasterPTY::write(FileDescription&, u64, const UserOrKernelBuffer& buffer, size_t size) @@ -62,7 +81,7 @@ bool MasterPTY::can_read(const FileDescription&, size_t) const { if (!m_slave) return true; - return !m_buffer.is_empty(); + return !m_buffer->is_empty(); } bool MasterPTY::can_write(const FileDescription&, size_t) const @@ -83,14 +102,14 @@ KResultOr MasterPTY::on_slave_write(const UserOrKernelBuffer& data, size { if (m_closed) return EIO; - return m_buffer.write(data, size); + return m_buffer->write(data, size); } bool MasterPTY::can_write_from_slave() const { if (m_closed) return true; - return m_buffer.space_for_writing(); + return m_buffer->space_for_writing(); } KResult MasterPTY::close() diff --git a/Kernel/TTY/MasterPTY.h b/Kernel/TTY/MasterPTY.h index a1c9274046..5ec21dced4 100644 --- a/Kernel/TTY/MasterPTY.h +++ b/Kernel/TTY/MasterPTY.h @@ -16,7 +16,7 @@ class SlavePTY; class MasterPTY final : public CharacterDevice { public: - explicit MasterPTY(unsigned index); + [[nodiscard]] static RefPtr try_create(unsigned index); virtual ~MasterPTY() override; unsigned index() const { return m_index; } @@ -33,6 +33,7 @@ public: virtual String device_name() const override; private: + explicit MasterPTY(unsigned index, NonnullOwnPtr buffer); // ^CharacterDevice virtual KResultOr read(FileDescription&, u64, UserOrKernelBuffer&, size_t) override; virtual KResultOr write(FileDescription&, u64, const UserOrKernelBuffer&, size_t) override; @@ -46,7 +47,7 @@ private: RefPtr m_slave; unsigned m_index; bool m_closed { false }; - DoubleBuffer m_buffer; + NonnullOwnPtr m_buffer; String m_pts_name; }; diff --git a/Kernel/TTY/PTYMultiplexer.cpp b/Kernel/TTY/PTYMultiplexer.cpp index 50ad2133e8..0f0dae7415 100644 --- a/Kernel/TTY/PTYMultiplexer.cpp +++ b/Kernel/TTY/PTYMultiplexer.cpp @@ -40,7 +40,7 @@ KResultOr> PTYMultiplexer::open(int options) if (m_freelist.is_empty()) return EBUSY; auto master_index = m_freelist.take_last(); - auto master = try_create(master_index); + auto master = MasterPTY::try_create(master_index); if (!master) return ENOMEM; dbgln_if(PTMX_DEBUG, "PTYMultiplexer::open: Vending master {}", master->index());