1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-31 15:38:10 +00:00

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.
This commit is contained in:
Andreas Kling 2019-01-30 18:26:19 +01:00
parent 027d26cd5d
commit b4e478aa50
19 changed files with 104 additions and 12 deletions

View file

@ -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);