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