diff options
author | Andreas Kling <awesomekling@gmail.com> | 2019-01-30 18:26:19 +0100 |
---|---|---|
committer | Andreas Kling <awesomekling@gmail.com> | 2019-01-30 18:47:18 +0100 |
commit | b4e478aa508407b999766efea882e4ec4f2f3b6d (patch) | |
tree | f25cc9faa4c7e57a0d46f10532358f176164707d /Kernel/MasterPTY.cpp | |
parent | 027d26cd5d6dbfceef0c2ade42a51068dcdcf43f (diff) | |
download | serenity-b4e478aa508407b999766efea882e4ec4f2f3b6d.zip |
Deallocate PTY's when they close.
This required a fair bit of plumbing. The CharacterDevice::close() virtual
will now be closed by ~FileDescriptor(), allowing device implementations to
do custom cleanup at that point.
One big problem remains: if the master PTY is closed before the slave PTY,
we go into crashy land.
Diffstat (limited to 'Kernel/MasterPTY.cpp')
-rw-r--r-- | Kernel/MasterPTY.cpp | 22 |
1 files changed, 20 insertions, 2 deletions
diff --git a/Kernel/MasterPTY.cpp b/Kernel/MasterPTY.cpp index 5a688072c4..2f6a90896a 100644 --- a/Kernel/MasterPTY.cpp +++ b/Kernel/MasterPTY.cpp @@ -1,15 +1,18 @@ #include "MasterPTY.h" #include "SlavePTY.h" +#include "PTYMultiplexer.h" +#include <LibC/errno_numbers.h> MasterPTY::MasterPTY(unsigned index) : CharacterDevice(10, index) - , m_slave(*new SlavePTY(*this, index)) + , m_slave(adopt(*new SlavePTY(*this, index))) , m_index(index) { } MasterPTY::~MasterPTY() { + PTYMultiplexer::the().notify_master_destroyed(Badge<MasterPTY>(), m_index); } String MasterPTY::pts_name() const @@ -19,17 +22,23 @@ String MasterPTY::pts_name() const ssize_t MasterPTY::read(Process&, byte* buffer, size_t size) { + if (!m_slave && m_buffer.is_empty()) + return 0; return m_buffer.read(buffer, size); } ssize_t MasterPTY::write(Process&, const byte* buffer, size_t size) { - m_slave.on_master_write(buffer, size); + if (!m_slave) + return -EIO; + m_slave->on_master_write(buffer, size); return size; } bool MasterPTY::can_read(Process&) const { + if (!m_slave) + return true; return !m_buffer.is_empty(); } @@ -38,6 +47,15 @@ bool MasterPTY::can_write(Process&) const return true; } +void MasterPTY::notify_slave_closed(Badge<SlavePTY>) +{ + dbgprintf("MasterPTY(%u): slave closed, my retains: %u, slave retains: %u\n", m_index, retain_count(), m_slave->retain_count()); + // +1 retain for my MasterPTY::m_slave + // +1 retain for FileDescriptor::m_device + if (m_slave->retain_count() == 2) + m_slave = nullptr; +} + void MasterPTY::on_slave_write(const byte* data, size_t size) { m_buffer.write(data, size); |