Kernel: Don't assume paths of TTYs and pseudo terminals anymore

The obsolete ttyname and ptsname syscalls are removed.
LibC doesn't rely on these anymore, and it helps simplifying the Kernel
in many places, so it's an overall an improvement.

In addition to that, /proc/PID/tty node is removed too as it is not
needed anymore by userspace to get the attached TTY of a process, as
/dev/tty (which is already a character device) represents that as well.
This commit is contained in:
Liav A 2022-02-15 21:41:41 +02:00 committed by Andreas Kling
parent de7566c2c4
commit b5ef900ccd
Notes: sideshowbarker 2024-07-17 16:53:04 +09:00
19 changed files with 13 additions and 141 deletions

View file

@ -134,7 +134,6 @@ enum class NeedsBigProcessLock {
S(profiling_enable, NeedsBigProcessLock::Yes) \
S(profiling_free_buffer, NeedsBigProcessLock::Yes) \
S(ptrace, NeedsBigProcessLock::Yes) \
S(ptsname, NeedsBigProcessLock::Yes) \
S(purge, NeedsBigProcessLock::Yes) \
S(read, NeedsBigProcessLock::Yes) \
S(pread, NeedsBigProcessLock::Yes) \
@ -181,7 +180,6 @@ enum class NeedsBigProcessLock {
S(sync, NeedsBigProcessLock::No) \
S(sysconf, NeedsBigProcessLock::No) \
S(times, NeedsBigProcessLock::Yes) \
S(ttyname, NeedsBigProcessLock::Yes) \
S(umask, NeedsBigProcessLock::Yes) \
S(umount, NeedsBigProcessLock::Yes) \
S(uname, NeedsBigProcessLock::No) \

View file

@ -268,7 +268,6 @@ set(KERNEL_SOURCES
Syscalls/sysconf.cpp
Syscalls/thread.cpp
Syscalls/times.cpp
Syscalls/ttyname.cpp
Syscalls/umask.cpp
Syscalls/uname.cpp
Syscalls/unlink.cpp

View file

@ -309,8 +309,6 @@ ErrorOr<NonnullRefPtr<Inode>> ProcFSProcessDirectoryInode::lookup(StringView nam
return TRY(ProcFSProcessPropertyInode::try_create_for_pid_property(procfs(), SegmentedProcFSIndex::MainProcessProperty::PerformanceEvents, associated_pid()));
if (name == "vm"sv)
return TRY(ProcFSProcessPropertyInode::try_create_for_pid_property(procfs(), SegmentedProcFSIndex::MainProcessProperty::VirtualMemoryStats, associated_pid()));
if (name == "tty"sv)
return TRY(ProcFSProcessPropertyInode::try_create_for_pid_property(procfs(), SegmentedProcFSIndex::MainProcessProperty::TTYLink, associated_pid()));
return ENOENT;
}
@ -447,8 +445,6 @@ static mode_t determine_procfs_process_inode_mode(SegmentedProcFSIndex::ProcessS
return S_IFLNK | 0777;
if (main_property == SegmentedProcFSIndex::MainProcessProperty::CurrentWorkDirectoryLink)
return S_IFLNK | 0777;
if (main_property == SegmentedProcFSIndex::MainProcessProperty::TTYLink)
return S_IFLNK | 0777;
return S_IFREG | 0400;
}
@ -552,8 +548,6 @@ ErrorOr<void> ProcFSProcessPropertyInode::try_to_acquire_data(Process& process,
return process.procfs_get_perf_events(builder);
case SegmentedProcFSIndex::MainProcessProperty::VirtualMemoryStats:
return process.procfs_get_virtual_memory_stats(builder);
case SegmentedProcFSIndex::MainProcessProperty::TTYLink:
return process.procfs_get_tty_link(builder);
default:
VERIFY_NOT_REACHED();
}

View file

@ -498,7 +498,6 @@ private:
TRY(process_object.add("nfds", process.fds().with_shared([](auto& fds) { return fds.open_count(); })));
TRY(process_object.add("name", process.name()));
TRY(process_object.add("executable", process.executable() ? TRY(process.executable()->try_serialize_absolute_path())->view() : ""sv));
TRY(process_object.add("tty", process.tty() ? process.tty()->tty_name().view() : "notty"sv));
TRY(process_object.add("amount_virtual", process.address_space().amount_virtual()));
TRY(process_object.add("amount_resident", process.address_space().amount_resident()));
TRY(process_object.add("amount_dirty_private", process.address_space().amount_dirty_private()));

View file

@ -326,8 +326,6 @@ public:
ErrorOr<FlatPtr> sys$sethostname(Userspace<const char*>, size_t);
ErrorOr<FlatPtr> sys$uname(Userspace<utsname*>);
ErrorOr<FlatPtr> sys$readlink(Userspace<const Syscall::SC_readlink_params*>);
ErrorOr<FlatPtr> sys$ttyname(int fd, Userspace<char*>, size_t);
ErrorOr<FlatPtr> sys$ptsname(int fd, Userspace<char*>, size_t);
ErrorOr<FlatPtr> sys$fork(RegisterState&);
ErrorOr<FlatPtr> sys$execve(Userspace<const Syscall::SC_execve_params*>);
ErrorOr<FlatPtr> sys$dup2(int old_fd, int new_fd);
@ -589,7 +587,6 @@ public:
ErrorOr<size_t> procfs_get_file_description_link(unsigned fd, KBufferBuilder& builder) const;
ErrorOr<void> traverse_file_descriptions_directory(FileSystemID, Function<ErrorOr<void>(FileSystem::DirectoryEntryView const&)> callback) const;
ErrorOr<NonnullRefPtr<Inode>> lookup_file_descriptions_directory(const ProcFS&, StringView name) const;
ErrorOr<void> procfs_get_tty_link(KBufferBuilder& builder) const;
private:
inline PerformanceEventBuffer* current_perf_events_buffer()

View file

@ -30,7 +30,6 @@ enum class MainProcessProperty {
CurrentWorkDirectoryLink = 5,
PerformanceEvents = 6,
VirtualMemoryStats = 7,
TTYLink = 8,
};
enum class ProcessSubDirectory {

View file

@ -62,7 +62,6 @@ ErrorOr<void> Process::ProcessProcFSTraits::traverse_as_directory(FileSystemID f
TRY(callback({ "cwd", { fsid, SegmentedProcFSIndex::build_segmented_index_for_main_property_in_pid_directory(process->pid(), SegmentedProcFSIndex::MainProcessProperty::CurrentWorkDirectoryLink) }, DT_LNK }));
TRY(callback({ "perf_events", { fsid, SegmentedProcFSIndex::build_segmented_index_for_main_property_in_pid_directory(process->pid(), SegmentedProcFSIndex::MainProcessProperty::PerformanceEvents) }, DT_REG }));
TRY(callback({ "vm", { fsid, SegmentedProcFSIndex::build_segmented_index_for_main_property_in_pid_directory(process->pid(), SegmentedProcFSIndex::MainProcessProperty::VirtualMemoryStats) }, DT_REG }));
TRY(callback({ "tty", { fsid, SegmentedProcFSIndex::build_segmented_index_for_main_property_in_pid_directory(process->pid(), SegmentedProcFSIndex::MainProcessProperty::TTYLink) }, DT_LNK }));
return {};
}

View file

@ -294,11 +294,4 @@ ErrorOr<void> Process::procfs_get_binary_link(KBufferBuilder& builder) const
return builder.append(TRY(custody->try_serialize_absolute_path())->view());
}
ErrorOr<void> Process::procfs_get_tty_link(KBufferBuilder& builder) const
{
if (m_tty.is_null())
return Error::from_errno(ENOENT);
return builder.append(m_tty->tty_name().view());
}
}

View file

@ -1,43 +0,0 @@
/*
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <Kernel/FileSystem/OpenFileDescription.h>
#include <Kernel/Process.h>
#include <Kernel/TTY/MasterPTY.h>
#include <Kernel/TTY/TTY.h>
namespace Kernel {
ErrorOr<FlatPtr> Process::sys$ttyname(int fd, Userspace<char*> buffer, size_t size)
{
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
TRY(require_promise(Pledge::tty));
auto description = TRY(open_file_description(fd));
if (!description->is_tty())
return ENOTTY;
auto const& tty_name = description->tty()->tty_name();
if (size < tty_name.length() + 1)
return ERANGE;
TRY(copy_to_user(buffer, tty_name.characters(), tty_name.length() + 1));
return 0;
}
ErrorOr<FlatPtr> Process::sys$ptsname(int fd, Userspace<char*> buffer, size_t size)
{
VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this)
TRY(require_promise(Pledge::tty));
auto description = TRY(open_file_description(fd));
auto* master_pty = description->master_pty();
if (!master_pty)
return ENOTTY;
auto const& pts_name = master_pty->pts_name();
if (size < pts_name.length() + 1)
return ERANGE;
TRY(copy_to_user(buffer, pts_name.characters(), pts_name.length() + 1));
return 0;
}
}

View file

@ -18,23 +18,19 @@ namespace Kernel {
ErrorOr<NonnullRefPtr<MasterPTY>> MasterPTY::try_create(unsigned int index)
{
auto pts_name = TRY(KString::formatted("/dev/pts/{}", index));
auto tty_name = TRY(pts_name->try_clone());
auto buffer = TRY(DoubleBuffer::try_create());
auto master_pty = TRY(adopt_nonnull_ref_or_enomem(new (nothrow) MasterPTY(index, move(buffer), move(pts_name))));
auto slave_pty = TRY(adopt_nonnull_ref_or_enomem(new (nothrow) SlavePTY(*master_pty, index, move(tty_name))));
auto master_pty = TRY(adopt_nonnull_ref_or_enomem(new (nothrow) MasterPTY(index, move(buffer))));
auto slave_pty = TRY(adopt_nonnull_ref_or_enomem(new (nothrow) SlavePTY(*master_pty, index)));
master_pty->m_slave = slave_pty;
master_pty->after_inserting();
slave_pty->after_inserting();
return master_pty;
}
MasterPTY::MasterPTY(unsigned index, NonnullOwnPtr<DoubleBuffer> buffer, NonnullOwnPtr<KString> pts_name)
MasterPTY::MasterPTY(unsigned index, NonnullOwnPtr<DoubleBuffer> buffer)
: CharacterDevice(200, index)
, m_index(index)
, m_buffer(move(buffer))
, m_pts_name(move(pts_name))
{
auto& process = Process::current();
set_uid(process.uid());
@ -52,11 +48,6 @@ MasterPTY::~MasterPTY()
PTYMultiplexer::the().notify_master_destroyed({}, m_index);
}
KString const& MasterPTY::pts_name() const
{
return *m_pts_name;
}
ErrorOr<size_t> MasterPTY::read(OpenFileDescription&, u64, UserOrKernelBuffer& buffer, size_t size)
{
if (!m_slave && m_buffer->is_empty())
@ -140,7 +131,7 @@ ErrorOr<void> MasterPTY::ioctl(OpenFileDescription& description, unsigned reques
ErrorOr<NonnullOwnPtr<KString>> MasterPTY::pseudo_path(const OpenFileDescription&) const
{
return KString::formatted("ptm:{}", m_pts_name);
return KString::formatted("ptm:{}", m_index);
}
}

View file

@ -20,7 +20,6 @@ public:
virtual ~MasterPTY() override;
unsigned index() const { return m_index; }
KString const& pts_name() const;
ErrorOr<size_t> on_slave_write(const UserOrKernelBuffer&, size_t);
bool can_write_from_slave() const;
void notify_slave_closed(Badge<SlavePTY>);
@ -29,7 +28,7 @@ public:
virtual ErrorOr<NonnullOwnPtr<KString>> pseudo_path(const OpenFileDescription&) const override;
private:
explicit MasterPTY(unsigned index, NonnullOwnPtr<DoubleBuffer> buffer, NonnullOwnPtr<KString> pts_name);
explicit MasterPTY(unsigned index, NonnullOwnPtr<DoubleBuffer> buffer);
// ^CharacterDevice
virtual ErrorOr<size_t> read(OpenFileDescription&, u64, UserOrKernelBuffer&, size_t) override;
virtual ErrorOr<size_t> write(OpenFileDescription&, u64, const UserOrKernelBuffer&, size_t) override;
@ -44,7 +43,6 @@ private:
unsigned m_index;
bool m_closed { false };
NonnullOwnPtr<DoubleBuffer> m_buffer;
NonnullOwnPtr<KString> m_pts_name;
};
}

View file

@ -36,11 +36,10 @@ bool SlavePTY::unref() const
return did_hit_zero;
}
SlavePTY::SlavePTY(MasterPTY& master, unsigned index, NonnullOwnPtr<KString> tty_name)
SlavePTY::SlavePTY(MasterPTY& master, unsigned index)
: TTY(201, index)
, m_master(master)
, m_index(index)
, m_tty_name(move(tty_name))
{
auto& process = Process::current();
set_uid(process.uid());
@ -55,11 +54,6 @@ SlavePTY::~SlavePTY()
dbgln_if(SLAVEPTY_DEBUG, "~SlavePTY({})", m_index);
}
KString const& SlavePTY::tty_name() const
{
return *m_tty_name;
}
void SlavePTY::echo(u8 ch)
{
if (should_echo_input()) {

View file

@ -27,7 +27,6 @@ public:
private:
// ^TTY
virtual KString const& tty_name() const override;
virtual ErrorOr<size_t> on_tty_write(const UserOrKernelBuffer&, size_t) override;
virtual void echo(u8) override;
@ -39,12 +38,11 @@ private:
virtual ErrorOr<void> close() override;
friend class MasterPTY;
SlavePTY(MasterPTY&, unsigned index, NonnullOwnPtr<KString> pts_name);
SlavePTY(MasterPTY&, unsigned index);
RefPtr<MasterPTY> m_master;
time_t m_time_of_last_write { 0 };
unsigned m_index { 0 };
NonnullOwnPtr<KString> m_tty_name;
mutable IntrusiveListNode<SlavePTY> m_list_node;

View file

@ -183,22 +183,18 @@ void TTY::emit(u8 ch, bool do_evaluate_block_conditions)
if (should_generate_signals()) {
if (ch == m_termios.c_cc[VINFO]) {
dbgln("{}: VINFO pressed!", tty_name());
generate_signal(SIGINFO);
return;
}
if (ch == m_termios.c_cc[VINTR]) {
dbgln("{}: VINTR pressed!", tty_name());
generate_signal(SIGINT);
return;
}
if (ch == m_termios.c_cc[VQUIT]) {
dbgln("{}: VQUIT pressed!", tty_name());
generate_signal(SIGQUIT);
return;
}
if (ch == m_termios.c_cc[VSUSP]) {
dbgln("{}: VSUSP pressed!", tty_name());
generate_signal(SIGTSTP);
if (auto original_process_parent = m_original_process_parent.strong_ref()) {
[[maybe_unused]] auto rc = original_process_parent->send_signal(SIGCHLD, nullptr);
@ -361,10 +357,10 @@ void TTY::generate_signal(int signal)
return;
if (should_flush_on_signal())
flush_input();
dbgln_if(TTY_DEBUG, "{}: Send signal {} to everyone in pgrp {}", tty_name(), signal, pgid().value());
dbgln_if(TTY_DEBUG, "Send signal {} to everyone in pgrp {}", signal, pgid().value());
InterruptDisabler disabler; // FIXME: Iterate over a set of process handles instead?
Process::for_each_in_pgrp(pgid(), [&](auto& process) {
dbgln_if(TTY_DEBUG, "{}: Send signal {} to {}", tty_name(), signal, process);
dbgln_if(TTY_DEBUG, "Send signal {} to {}", signal, process);
// FIXME: Should this error be propagated somehow?
[[maybe_unused]] auto rc = process.send_signal(signal, nullptr);
});
@ -382,8 +378,7 @@ ErrorOr<void> TTY::set_termios(const termios& t)
ErrorOr<void> rc;
m_termios = t;
dbgln_if(TTY_DEBUG, "{} set_termios: ECHO={}, ISIG={}, ICANON={}, ECHOE={}, ECHOK={}, ECHONL={}, ISTRIP={}, ICRNL={}, INLCR={}, IGNCR={}, OPOST={}, ONLCR={}",
tty_name(),
dbgln_if(TTY_DEBUG, "set_termios: ECHO={}, ISIG={}, ICANON={}, ECHOE={}, ECHOK={}, ECHONL={}, ISTRIP={}, ICRNL={}, INLCR={}, IGNCR={}, OPOST={}, ONLCR={}",
should_echo_input(),
should_generate_signals(),
in_canonical_mode(),
@ -571,11 +566,6 @@ ErrorOr<void> TTY::ioctl(OpenFileDescription&, unsigned request, Userspace<void*
return EINVAL;
}
ErrorOr<NonnullOwnPtr<KString>> TTY::pseudo_path(const OpenFileDescription&) const
{
return tty_name().try_clone();
}
void TTY::set_size(unsigned short columns, unsigned short rows)
{
m_rows = rows;

View file

@ -26,9 +26,6 @@ public:
virtual bool can_read(const OpenFileDescription&, u64) const override;
virtual bool can_write(const OpenFileDescription&, u64) const override;
virtual ErrorOr<void> ioctl(OpenFileDescription&, unsigned request, Userspace<void*> arg) override final;
virtual ErrorOr<NonnullOwnPtr<KString>> pseudo_path(const OpenFileDescription&) const override;
virtual KString const& tty_name() const = 0;
unsigned short rows() const { return m_rows; }
unsigned short columns() const { return m_columns; }

View file

@ -104,9 +104,7 @@ void VirtualConsole::set_graphical(bool graphical)
UNMAP_AFTER_INIT NonnullRefPtr<VirtualConsole> VirtualConsole::create(size_t index)
{
auto pts_name = MUST(KString::formatted("/dev/tty/{}", index));
auto virtual_console_or_error = DeviceManagement::try_create_device<VirtualConsole>(index, move(pts_name));
auto virtual_console_or_error = DeviceManagement::try_create_device<VirtualConsole>(index);
// FIXME: Find a way to propagate errors
VERIFY(!virtual_console_or_error.is_error());
return virtual_console_or_error.release_value();
@ -176,10 +174,9 @@ void VirtualConsole::refresh_after_resolution_change()
flush_dirty_lines();
}
UNMAP_AFTER_INIT VirtualConsole::VirtualConsole(const unsigned index, NonnullOwnPtr<KString> tty_name)
UNMAP_AFTER_INIT VirtualConsole::VirtualConsole(const unsigned index)
: TTY(4, index)
, m_index(index)
, m_tty_name(move(tty_name))
, m_console_impl(*this)
{
initialize();

View file

@ -84,13 +84,12 @@ public:
void emit_char(char);
private:
explicit VirtualConsole(const unsigned index, NonnullOwnPtr<KString> tty_name);
explicit VirtualConsole(const unsigned index);
// ^KeyboardClient
virtual void on_key_pressed(KeyEvent) override;
// ^TTY
virtual ErrorOr<size_t> on_tty_write(const UserOrKernelBuffer&, size_t) override;
virtual KString const& tty_name() const override { return *m_tty_name; }
virtual void echo(u8) override;
// ^TerminalClient
@ -112,8 +111,6 @@ private:
bool m_active { false };
bool m_graphical { false };
NonnullOwnPtr<KString> m_tty_name;
private:
void initialize();

View file

@ -214,7 +214,6 @@ private:
int virt$poll(FlatPtr);
int virt$profiling_disable(pid_t);
int virt$profiling_enable(pid_t);
int virt$ptsname(int fd, FlatPtr buffer, size_t buffer_size);
int virt$purge(int mode);
u32 virt$read(int, FlatPtr, ssize_t);
int virt$readlink(FlatPtr);
@ -246,7 +245,6 @@ private:
int virt$symlink(FlatPtr address);
void virt$sync();
u32 virt$sysconf(u32 name);
int virt$ttyname(int fd, FlatPtr buffer, size_t buffer_size);
mode_t virt$umask(mode_t);
int virt$uname(FlatPtr params_addr);
int virt$unlink(FlatPtr path, size_t path_length);

View file

@ -184,8 +184,6 @@ u32 Emulator::virt_syscall(u32 function, u32 arg1, u32 arg2, u32 arg3)
return virt$profiling_disable(arg1);
case SC_profiling_enable:
return virt$profiling_enable(arg1);
case SC_ptsname:
return virt$ptsname(arg1, arg2, arg3);
case SC_purge:
return virt$purge(arg1);
case SC_read:
@ -249,8 +247,6 @@ u32 Emulator::virt_syscall(u32 function, u32 arg1, u32 arg2, u32 arg3)
return 0;
case SC_sysconf:
return virt$sysconf(arg1);
case SC_ttyname:
return virt$ttyname(arg1, arg2, arg3);
case SC_umask:
return virt$umask(arg1);
case SC_uname:
@ -1454,19 +1450,6 @@ int Emulator::virt$setpgid(pid_t pid, pid_t pgid)
return syscall(SC_setpgid, pid, pgid);
}
int Emulator::virt$ttyname(int fd, FlatPtr buffer, size_t buffer_size)
{
auto buffer_result = ByteBuffer::create_zeroed(buffer_size);
if (buffer_result.is_error())
return -ENOMEM;
auto& host_buffer = buffer_result.value();
int rc = syscall(SC_ttyname, fd, host_buffer.data(), host_buffer.size());
if (rc < 0)
return rc;
mmu().copy_to_vm(buffer, host_buffer.data(), host_buffer.size());
return rc;
}
int Emulator::virt$getcwd(FlatPtr buffer, size_t buffer_size)
{
auto buffer_result = ByteBuffer::create_zeroed(buffer_size);
@ -1642,12 +1625,6 @@ u32 Emulator::virt$allocate_tls(FlatPtr initial_data, size_t size)
return tls_base;
}
int Emulator::virt$ptsname(int fd, FlatPtr buffer, size_t buffer_size)
{
auto pts = mmu().copy_buffer_from_vm(buffer, buffer_size);
return syscall(SC_ptsname, fd, pts.data(), pts.size());
}
int Emulator::virt$beep()
{
return syscall(SC_beep);