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.
This commit is contained in:
Daniel Bertalan 2021-12-12 13:01:13 +01:00 committed by Andreas Kling
parent 7ca2315659
commit 8dd11ae717
6 changed files with 22 additions and 0 deletions

View file

@ -318,6 +318,8 @@ 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;
}
@ -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<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

@ -576,6 +576,7 @@ 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

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

View file

@ -62,6 +62,7 @@ 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

@ -15,6 +15,7 @@
#include <Kernel/Memory/MemoryManager.h>
#include <Kernel/Process.h>
#include <Kernel/ProcessExposed.h>
#include <Kernel/TTY/TTY.h>
namespace Kernel {
@ -281,4 +282,11 @@ ErrorOr<void> Process::procfs_get_binary_link(KBufferBuilder& builder) const
return builder.append(custody->absolute_path().bytes());
}
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().characters());
}
}

View file

@ -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);