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();
|
2022-01-08 15:43:56 +01:00
|
|
|
const_cast<SlavePTY&>(*this).revoke_weak_ptrs();
|
2021-08-16 22:13:58 +02:00
|
|
|
return true;
|
|
|
|
|
});
|
2021-09-10 14:44:46 +03:00
|
|
|
if (did_hit_zero) {
|
2021-12-29 01:00:29 +02:00
|
|
|
const_cast<SlavePTY&>(*this).will_be_destroyed();
|
2021-08-16 22:13:58 +02:00
|
|
|
delete this;
|
2021-09-10 14:44:46 +03:00
|
|
|
}
|
2021-08-16 22:13:58 +02:00
|
|
|
return did_hit_zero;
|
|
|
|
|
}
|
|
|
|
|
|
2022-02-15 21:41:41 +02: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-08-19 22:45:07 +03:00
|
|
|
auto& process = Process::current();
|
2022-08-20 18:21:01 -04:00
|
|
|
auto credentials = process.credentials();
|
|
|
|
|
set_uid(credentials->uid());
|
|
|
|
|
set_gid(credentials->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
|
|
|
}
|
|
|
|
|
|
2022-03-26 09:06:30 +03:00
|
|
|
ErrorOr<NonnullOwnPtr<KString>> SlavePTY::pseudo_name() const
|
|
|
|
|
{
|
|
|
|
|
return KString::formatted("pts:{}", m_index);
|
|
|
|
|
}
|
|
|
|
|
|
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
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-04-01 20:58:27 +03:00
|
|
|
void SlavePTY::on_master_write(UserOrKernelBuffer const& 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
|
|
|
}
|
|
|
|
|
|
2022-04-01 20:58:27 +03:00
|
|
|
ErrorOr<size_t> SlavePTY::on_tty_write(UserOrKernelBuffer const& 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
|
|
|
|
2022-04-01 20:58:27 +03:00
|
|
|
bool SlavePTY::can_write(OpenFileDescription const&, u64) 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
|
|
|
|
2022-04-01 20:58:27 +03:00
|
|
|
bool SlavePTY::can_read(OpenFileDescription const& description, u64 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-11-08 00:51:39 +01:00
|
|
|
ErrorOr<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
|
|
|
}
|
|
|
|
|
|
2021-11-08 00:51:39 +01:00
|
|
|
ErrorOr<void> SlavePTY::close()
|
2019-01-30 18:26:19 +01:00
|
|
|
{
|
2019-05-31 15:44:04 +02:00
|
|
|
m_master->notify_slave_closed({});
|
2021-11-08 00:51:39 +01:00
|
|
|
return {};
|
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
|
|
|
}
|