summaryrefslogtreecommitdiff
path: root/Kernel/MasterPTY.cpp
diff options
context:
space:
mode:
authorAndreas Kling <awesomekling@gmail.com>2019-01-30 18:26:19 +0100
committerAndreas Kling <awesomekling@gmail.com>2019-01-30 18:47:18 +0100
commitb4e478aa508407b999766efea882e4ec4f2f3b6d (patch)
treef25cc9faa4c7e57a0d46f10532358f176164707d /Kernel/MasterPTY.cpp
parent027d26cd5d6dbfceef0c2ade42a51068dcdcf43f (diff)
downloadserenity-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.cpp22
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);