diff --git a/Kernel/Devices/SelfTTYDevice.cpp b/Kernel/Devices/SelfTTYDevice.cpp index 20bbef1d5d..ddd3129014 100644 --- a/Kernel/Devices/SelfTTYDevice.cpp +++ b/Kernel/Devices/SelfTTYDevice.cpp @@ -26,7 +26,7 @@ ErrorOr> SelfTTYDevice::open(int options) if (!Process::has_current()) return Error::from_errno(ESRCH); auto& current_process = Process::current(); - LockRefPtr tty = current_process.tty(); + auto tty = current_process.tty(); if (!tty) return Error::from_errno(ENXIO); auto description = TRY(OpenFileDescription::try_create(*tty)); diff --git a/Kernel/FileSystem/SysFS/Subsystems/Kernel/Processes.cpp b/Kernel/FileSystem/SysFS/Subsystems/Kernel/Processes.cpp index 85663ce475..0f4f82ca97 100644 --- a/Kernel/FileSystem/SysFS/Subsystems/Kernel/Processes.cpp +++ b/Kernel/FileSystem/SysFS/Subsystems/Kernel/Processes.cpp @@ -65,7 +65,10 @@ ErrorOr SysFSOverallProcesses::try_generate(KBufferBuilder& builder) } TRY(process_object.add("pid"sv, process.pid().value())); - TRY(process_object.add("pgid"sv, process.tty() ? process.tty()->pgid().value() : 0)); + ProcessGroupID tty_pgid = 0; + if (auto tty = process.tty()) + tty_pgid = tty->pgid(); + TRY(process_object.add("pgid"sv, tty_pgid.value())); TRY(process_object.add("pgp"sv, process.pgid().value())); TRY(process_object.add("sid"sv, process.sid().value())); auto credentials = process.credentials(); diff --git a/Kernel/Process.cpp b/Kernel/Process.cpp index bd1328ac04..6003802937 100644 --- a/Kernel/Process.cpp +++ b/Kernel/Process.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2022, Andreas Kling + * Copyright (c) 2018-2023, Andreas Kling * * SPDX-License-Identifier: BSD-2-Clause */ @@ -208,7 +208,7 @@ void Process::register_new(Process& process) }); } -ErrorOr Process::create_user_process(StringView path, UserID uid, GroupID gid, Vector> arguments, Vector> environment, TTY* tty) +ErrorOr Process::create_user_process(StringView path, UserID uid, GroupID gid, Vector> arguments, Vector> environment, RefPtr tty) { auto parts = path.split_view('/'); if (arguments.is_empty()) { @@ -284,7 +284,7 @@ void Process::unprotect_data() }); } -ErrorOr Process::create(NonnullOwnPtr name, UserID uid, GroupID gid, ProcessID ppid, bool is_kernel_process, RefPtr current_directory, RefPtr executable, TTY* tty, Process* fork_parent) +ErrorOr Process::create(NonnullOwnPtr name, UserID uid, GroupID gid, ProcessID ppid, bool is_kernel_process, RefPtr current_directory, RefPtr executable, RefPtr tty, Process* fork_parent) { OwnPtr new_address_space; if (fork_parent) { @@ -305,7 +305,7 @@ ErrorOr Process::create(NonnullOwnPtr n return ProcessAndFirstThread { move(process), move(first_thread) }; } -Process::Process(NonnullOwnPtr name, NonnullRefPtr credentials, ProcessID ppid, bool is_kernel_process, RefPtr current_directory, RefPtr executable, TTY* tty, UnveilNode unveil_tree, UnveilNode exec_unveil_tree) +Process::Process(NonnullOwnPtr name, NonnullRefPtr credentials, ProcessID ppid, bool is_kernel_process, RefPtr current_directory, RefPtr executable, RefPtr tty, UnveilNode unveil_tree, UnveilNode exec_unveil_tree) : m_name(move(name)) , m_is_kernel_process(is_kernel_process) , m_executable(move(executable)) @@ -758,7 +758,7 @@ void Process::finalize() TimerQueue::the().cancel_timer(timer.release_nonnull()); }); m_fds.with_exclusive([](auto& fds) { fds.clear(); }); - m_tty = nullptr; + m_tty.with([](auto& tty) { tty = nullptr; }); m_executable.with([](auto& executable) { executable = nullptr; }); m_jail_process_list.with([this](auto& list_ptr) { if (list_ptr) { @@ -835,7 +835,7 @@ void Process::die() // getting an EOF when the last process using the slave PTY dies. // If the master PTY owner relies on an EOF to know when to wait() on a // slave owner, we have to allow the PTY pair to be torn down. - m_tty = nullptr; + m_tty.with([](auto& tty) { tty = nullptr; }); VERIFY(m_threads_for_coredump.is_empty()); for_each_thread([&](auto& thread) { @@ -941,9 +941,19 @@ void Process::OpenFileDescriptionAndFlags::set(NonnullRefPtr Process::tty() { - m_tty = tty; + return m_tty.with([&](auto& tty) { return tty; }); +} + +RefPtr Process::tty() const +{ + return m_tty.with([&](auto& tty) { return tty; }); +} + +void Process::set_tty(RefPtr new_tty) +{ + m_tty.with([&](auto& tty) { swap(tty, new_tty); }); } ErrorOr Process::start_tracing_from(ProcessID tracer) diff --git a/Kernel/Process.h b/Kernel/Process.h index 43e6159555..6916b18ed5 100644 --- a/Kernel/Process.h +++ b/Kernel/Process.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2022, Andreas Kling + * Copyright (c) 2018-2023, Andreas Kling * * SPDX-License-Identifier: BSD-2-Clause */ @@ -198,7 +198,7 @@ public: } static ErrorOr create_kernel_process(NonnullOwnPtr name, void (*entry)(void*), void* entry_data = nullptr, u32 affinity = THREAD_AFFINITY_DEFAULT, RegisterProcess do_register = RegisterProcess::Yes); - static ErrorOr create_user_process(StringView path, UserID, GroupID, Vector> arguments, Vector> environment, TTY*); + static ErrorOr create_user_process(StringView path, UserID, GroupID, Vector> arguments, Vector> environment, RefPtr); static void register_new(Process&); ~Process(); @@ -466,8 +466,9 @@ public: [[noreturn]] void crash(int signal, Optional regs, bool out_of_memory = false); [[nodiscard]] siginfo_t wait_info() const; - const TTY* tty() const { return m_tty; } - void set_tty(TTY*); + RefPtr tty(); + RefPtr tty() const; + void set_tty(RefPtr); clock_t m_ticks_in_user { 0 }; clock_t m_ticks_in_kernel { 0 }; @@ -604,8 +605,8 @@ private: bool add_thread(Thread&); bool remove_thread(Thread&); - Process(NonnullOwnPtr name, NonnullRefPtr, ProcessID ppid, bool is_kernel_process, RefPtr current_directory, RefPtr executable, TTY* tty, UnveilNode unveil_tree, UnveilNode exec_unveil_tree); - static ErrorOr create(NonnullOwnPtr name, UserID, GroupID, ProcessID ppid, bool is_kernel_process, RefPtr current_directory = nullptr, RefPtr executable = nullptr, TTY* = nullptr, Process* fork_parent = nullptr); + Process(NonnullOwnPtr name, NonnullRefPtr, ProcessID ppid, bool is_kernel_process, RefPtr current_directory, RefPtr executable, RefPtr tty, UnveilNode unveil_tree, UnveilNode exec_unveil_tree); + static ErrorOr create(NonnullOwnPtr name, UserID, GroupID, ProcessID ppid, bool is_kernel_process, RefPtr current_directory = nullptr, RefPtr executable = nullptr, RefPtr = nullptr, Process* fork_parent = nullptr); ErrorOr> attach_resources(NonnullOwnPtr&&, Process* fork_parent); static ProcessID allocate_pid(); @@ -857,7 +858,7 @@ private: Vector> m_arguments; Vector> m_environment; - LockRefPtr m_tty; + SpinlockProtected, LockRank::None> m_tty; LockWeakPtr m_master_tls_region; diff --git a/Kernel/Syscalls/fork.cpp b/Kernel/Syscalls/fork.cpp index ad4f716a0c..8fcd8171ac 100644 --- a/Kernel/Syscalls/fork.cpp +++ b/Kernel/Syscalls/fork.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2020, Andreas Kling + * Copyright (c) 2018-2023, Andreas Kling * Copyright (c) 2023, Idan Horowitz * * SPDX-License-Identifier: BSD-2-Clause @@ -11,6 +11,7 @@ #include #include #include +#include namespace Kernel { @@ -21,7 +22,7 @@ ErrorOr Process::sys$fork(RegisterState& regs) auto child_name = TRY(name().with([](auto& name) { return name->try_clone(); })); auto credentials = this->credentials(); - auto child_and_first_thread = TRY(Process::create(move(child_name), credentials->uid(), credentials->gid(), pid(), m_is_kernel_process, current_directory(), executable(), m_tty, this)); + auto child_and_first_thread = TRY(Process::create(move(child_name), credentials->uid(), credentials->gid(), pid(), m_is_kernel_process, current_directory(), executable(), tty(), this)); auto& child = child_and_first_thread.process; auto& child_first_thread = child_and_first_thread.first_thread; diff --git a/Kernel/Syscalls/setpgid.cpp b/Kernel/Syscalls/setpgid.cpp index 11333df583..c331f39085 100644 --- a/Kernel/Syscalls/setpgid.cpp +++ b/Kernel/Syscalls/setpgid.cpp @@ -39,7 +39,7 @@ ErrorOr Process::sys$setsid() auto process_group = TRY(ProcessGroup::create(ProcessGroupID(pid().value()))); m_pg.with([&](auto& pg) { pg = move(process_group); }); - m_tty = nullptr; + m_tty.with([](auto& tty) { tty = nullptr; }); return with_mutable_protected_data([&](auto& protected_data) -> ErrorOr { protected_data.sid = pid().value(); return protected_data.sid.value();