From 8dd11ae717c2b720c3108805d3fb4bcae0d3b6f9 Mon Sep 17 00:00:00 2001 From: Daniel Bertalan Date: Sun, 12 Dec 2021 13:01:13 +0100 Subject: [PATCH] Kernel+SystemServer: Add /dev/tty This file refers to the controlling terminal associated with the current process. It's specified by POSIX, and is used by ports like openssh to interface with the terminal even if the standard input/output is redirected to somewhere else. Our implementation leverages ProcFS's existing facilities to create process-specific symbolic links. In our setup, `/dev/tty` is a symbolic link to `/proc/self/tty`, which itself is a symlink to the appropriate `/dev/pts` entry. If no TTY is attached, `/dev/tty` is left dangling. --- Kernel/FileSystem/ProcFS.cpp | 6 ++++++ Kernel/Process.h | 1 + Kernel/ProcessExposed.h | 1 + Kernel/ProcessProcFSTraits.cpp | 1 + Kernel/ProcessSpecificExposed.cpp | 8 ++++++++ Userland/Services/SystemServer/main.cpp | 5 +++++ 6 files changed, 22 insertions(+) diff --git a/Kernel/FileSystem/ProcFS.cpp b/Kernel/FileSystem/ProcFS.cpp index 05ae501b72..1cecfd30f7 100644 --- a/Kernel/FileSystem/ProcFS.cpp +++ b/Kernel/FileSystem/ProcFS.cpp @@ -318,6 +318,8 @@ ErrorOr> 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; } @@ -454,6 +456,8 @@ 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; } @@ -557,6 +561,8 @@ ErrorOr 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(); } diff --git a/Kernel/Process.h b/Kernel/Process.h index 0dbfb175c8..0e64e326cf 100644 --- a/Kernel/Process.h +++ b/Kernel/Process.h @@ -576,6 +576,7 @@ public: ErrorOr procfs_get_file_description_link(unsigned fd, KBufferBuilder& builder) const; ErrorOr traverse_file_descriptions_directory(FileSystemID, Function(FileSystem::DirectoryEntryView const&)> callback) const; ErrorOr> lookup_file_descriptions_directory(const ProcFS&, StringView name) const; + ErrorOr procfs_get_tty_link(KBufferBuilder& builder) const; private: inline PerformanceEventBuffer* current_perf_events_buffer() diff --git a/Kernel/ProcessExposed.h b/Kernel/ProcessExposed.h index c51b50dc14..e7feccffce 100644 --- a/Kernel/ProcessExposed.h +++ b/Kernel/ProcessExposed.h @@ -29,6 +29,7 @@ enum class MainProcessProperty { CurrentWorkDirectoryLink = 5, PerformanceEvents = 6, VirtualMemoryStats = 7, + TTYLink = 8, }; enum class ProcessSubDirectory { diff --git a/Kernel/ProcessProcFSTraits.cpp b/Kernel/ProcessProcFSTraits.cpp index 0bdbf1fdf1..ebf004a177 100644 --- a/Kernel/ProcessProcFSTraits.cpp +++ b/Kernel/ProcessProcFSTraits.cpp @@ -62,6 +62,7 @@ ErrorOr 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 {}; } diff --git a/Kernel/ProcessSpecificExposed.cpp b/Kernel/ProcessSpecificExposed.cpp index 175a4c2490..d19031aa67 100644 --- a/Kernel/ProcessSpecificExposed.cpp +++ b/Kernel/ProcessSpecificExposed.cpp @@ -15,6 +15,7 @@ #include #include #include +#include namespace Kernel { @@ -281,4 +282,11 @@ ErrorOr Process::procfs_get_binary_link(KBufferBuilder& builder) const return builder.append(custody->absolute_path().bytes()); } +ErrorOr 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().characters()); +} + } diff --git a/Userland/Services/SystemServer/main.cpp b/Userland/Services/SystemServer/main.cpp index 962394865b..1b020eea60 100644 --- a/Userland/Services/SystemServer/main.cpp +++ b/Userland/Services/SystemServer/main.cpp @@ -363,6 +363,11 @@ static void prepare_synthetic_filesystems() VERIFY_NOT_REACHED(); } + rc = symlink("/proc/self/tty", "/dev/tty"); + if (rc < 0) { + VERIFY_NOT_REACHED(); + } + populate_devfs(); rc = mkdir("/dev/pts", 0755);