2020-01-18 09:38:21 +01:00
|
|
|
/*
|
2021-08-16 22:13:58 +02:00
|
|
|
* Copyright (c) 2018-2021, Andreas Kling <kling@serenityos.org>
|
2020-01-18 09:38:21 +01:00
|
|
|
*
|
2021-04-22 01:24:48 -07:00
|
|
|
* SPDX-License-Identifier: BSD-2-Clause
|
2020-01-18 09:38:21 +01:00
|
|
|
*/
|
|
|
|
|
|
2021-08-16 22:13:58 +02:00
|
|
|
#include <AK/Singleton.h>
|
2021-01-25 16:07:10 +01:00
|
|
|
#include <Kernel/Debug.h>
|
2019-04-03 12:25:24 +02:00
|
|
|
#include <Kernel/FileSystem/DevPtsFS.h>
|
2019-01-31 05:55:30 +01:00
|
|
|
#include <Kernel/Process.h>
|
2021-07-11 12:02:15 -07:00
|
|
|
#include <Kernel/TTY/MasterPTY.h>
|
|
|
|
|
#include <Kernel/TTY/SlavePTY.h>
|
2019-01-15 06:30:19 +01:00
|
|
|
|
2020-02-16 01:27:42 +01:00
|
|
|
namespace Kernel {
|
|
|
|
|
|
2021-08-22 01:37:17 +02:00
|
|
|
static Singleton<SpinlockProtected<SlavePTY::List>> s_all_instances;
|
2021-08-16 22:13:58 +02:00
|
|
|
|
2021-08-22 01:37:17 +02:00
|
|
|
SpinlockProtected<SlavePTY::List>& SlavePTY::all_instances()
|
2021-08-16 22:13:58 +02:00
|
|
|
{
|
|
|
|
|
return s_all_instances;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool SlavePTY::unref() const
|
|
|
|
|
{
|
|
|
|
|
bool did_hit_zero = SlavePTY::all_instances().with([&](auto&) {
|
|
|
|
|
if (deref_base())
|
|
|
|
|
return false;
|
|
|
|
|
m_list_node.remove();
|
|
|
|
|
return true;
|
|
|
|
|
});
|
|
|
|
|
if (did_hit_zero)
|
|
|
|
|
delete this;
|
|
|
|
|
return did_hit_zero;
|
|
|
|
|
}
|
|
|
|
|
|
2019-01-16 02:11:50 +01:00
|
|
|
SlavePTY::SlavePTY(MasterPTY& master, unsigned index)
|
2019-12-09 21:03:39 +01:00
|
|
|
: TTY(201, index)
|
2019-01-16 02:11:50 +01:00
|
|
|
, m_master(master)
|
2019-01-15 06:30:19 +01:00
|
|
|
, m_index(index)
|
|
|
|
|
{
|
2021-02-17 16:37:11 +01:00
|
|
|
m_tty_name = String::formatted("/dev/pts/{}", m_index);
|
2021-08-19 22:45:07 +03:00
|
|
|
auto& process = Process::current();
|
|
|
|
|
set_uid(process.uid());
|
|
|
|
|
set_gid(process.gid());
|
2019-01-15 08:49:24 +01:00
|
|
|
set_size(80, 25);
|
2021-08-16 22:13:58 +02:00
|
|
|
|
|
|
|
|
SlavePTY::all_instances().with([&](auto& list) { list.append(*this); });
|
2019-01-15 06:30:19 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SlavePTY::~SlavePTY()
|
|
|
|
|
{
|
2021-02-07 15:33:24 +03:30
|
|
|
dbgln_if(SLAVEPTY_DEBUG, "~SlavePTY({})", m_index);
|
2019-01-15 06:30:19 +01:00
|
|
|
}
|
|
|
|
|
|
2021-05-12 22:47:06 +02:00
|
|
|
String const& SlavePTY::tty_name() const
|
2019-01-15 06:30:19 +01:00
|
|
|
{
|
2019-04-16 00:35:02 +02:00
|
|
|
return m_tty_name;
|
2019-01-15 06:30:19 +01:00
|
|
|
}
|
|
|
|
|
|
2019-10-20 19:12:00 +13:00
|
|
|
void SlavePTY::echo(u8 ch)
|
|
|
|
|
{
|
|
|
|
|
if (should_echo_input()) {
|
2020-09-11 21:11:07 -06:00
|
|
|
auto buffer = UserOrKernelBuffer::for_kernel_buffer(&ch);
|
2021-06-16 15:20:35 +02:00
|
|
|
[[maybe_unused]] auto result = m_master->on_slave_write(buffer, 1);
|
2019-10-20 19:12:00 +13:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-06-16 15:20:35 +02:00
|
|
|
void SlavePTY::on_master_write(const UserOrKernelBuffer& buffer, size_t size)
|
2019-01-15 06:30:19 +01:00
|
|
|
{
|
2021-08-31 23:44:55 -07:00
|
|
|
auto result = buffer.read_buffered<128>(size, [&](ReadonlyBytes data) {
|
|
|
|
|
for (const auto& byte : data)
|
|
|
|
|
emit(byte, false);
|
|
|
|
|
return data.size();
|
2020-09-11 21:11:07 -06:00
|
|
|
});
|
2021-05-13 09:08:44 +02:00
|
|
|
if (!result.is_error())
|
2020-11-29 16:05:27 -07:00
|
|
|
evaluate_block_conditions();
|
2019-01-15 06:30:19 +01:00
|
|
|
}
|
|
|
|
|
|
2021-06-16 15:20:35 +02:00
|
|
|
KResultOr<size_t> SlavePTY::on_tty_write(const UserOrKernelBuffer& data, size_t size)
|
2019-01-15 06:30:19 +01:00
|
|
|
{
|
2021-02-28 02:18:48 +01:00
|
|
|
m_time_of_last_write = kgettimeofday().to_truncated_seconds();
|
2019-02-05 13:09:01 +01:00
|
|
|
return m_master->on_slave_write(data, size);
|
2019-01-15 06:30:19 +01:00
|
|
|
}
|
2019-01-15 09:17:22 +01:00
|
|
|
|
2021-09-07 13:39:11 +02:00
|
|
|
bool SlavePTY::can_write(const OpenFileDescription&, size_t) const
|
2019-01-15 09:17:22 +01:00
|
|
|
{
|
2019-01-30 19:05:59 +01:00
|
|
|
return m_master->can_write_from_slave();
|
2019-01-15 09:17:22 +01:00
|
|
|
}
|
2019-01-30 18:26:19 +01:00
|
|
|
|
2021-09-07 13:39:11 +02:00
|
|
|
bool SlavePTY::can_read(const OpenFileDescription& description, size_t offset) const
|
2019-02-05 12:27:32 +01:00
|
|
|
{
|
|
|
|
|
if (m_master->is_closed())
|
|
|
|
|
return true;
|
2020-04-10 19:44:42 +10:00
|
|
|
return TTY::can_read(description, offset);
|
2019-02-05 12:27:32 +01:00
|
|
|
}
|
|
|
|
|
|
2021-09-07 13:39:11 +02:00
|
|
|
KResultOr<size_t> SlavePTY::read(OpenFileDescription& description, u64 offset, UserOrKernelBuffer& buffer, size_t size)
|
2019-02-05 12:27:32 +01:00
|
|
|
{
|
|
|
|
|
if (m_master->is_closed())
|
|
|
|
|
return 0;
|
2020-04-10 19:44:42 +10:00
|
|
|
return TTY::read(description, offset, buffer, size);
|
2019-02-05 12:27:32 +01:00
|
|
|
}
|
|
|
|
|
|
2020-06-02 19:20:05 +03:00
|
|
|
KResult SlavePTY::close()
|
2019-01-30 18:26:19 +01:00
|
|
|
{
|
2019-05-31 15:44:04 +02:00
|
|
|
m_master->notify_slave_closed({});
|
2020-06-02 19:20:05 +03:00
|
|
|
return KSuccess;
|
2019-01-30 18:26:19 +01:00
|
|
|
}
|
2020-02-16 01:27:42 +01:00
|
|
|
|
2021-08-22 15:59:47 +02:00
|
|
|
FileBlockerSet& SlavePTY::blocker_set()
|
2020-11-29 16:05:27 -07:00
|
|
|
{
|
2021-08-22 15:59:47 +02:00
|
|
|
return m_master->blocker_set();
|
2020-11-29 16:05:27 -07:00
|
|
|
}
|
|
|
|
|
|
2020-02-16 01:27:42 +01:00
|
|
|
}
|