Sfoglia il codice sorgente

Kernel: Create SelfTTYDevice class to help replace /dev/tty symlink

This will replace the /dev/tty symlink created by SystemServer, so
instead of a symlink, a character device will be created. When doing
read(2), write(2) and ioctl(2) on this device, it will "redirect" these
operations to the attached TTY of the current process.
Liav A 3 anni fa
parent
commit
12867d60ad

+ 1 - 0
Kernel/CMakeLists.txt

@@ -62,6 +62,7 @@ set(KERNEL_SOURCES
     Devices/PCISerialDevice.cpp
     Devices/PCSpeaker.cpp
     Devices/RandomDevice.cpp
+    Devices/SelfTTYDevice.cpp
     Devices/SerialDevice.cpp
     Devices/VMWareBackdoor.cpp
     Devices/ZeroDevice.cpp

+ 67 - 0
Kernel/Devices/SelfTTYDevice.cpp

@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2022, Liav A. <liavalb@hotmail.co.il>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#include <Kernel/Devices/DeviceManagement.h>
+#include <Kernel/Devices/SelfTTYDevice.h>
+#include <Kernel/Sections.h>
+#include <Kernel/TTY/TTY.h>
+
+namespace Kernel {
+
+UNMAP_AFTER_INIT NonnullRefPtr<SelfTTYDevice> SelfTTYDevice::must_create()
+{
+    auto self_tty_device_or_error = DeviceManagement::try_create_device<SelfTTYDevice>();
+    // FIXME: Find a way to propagate errors
+    VERIFY(!self_tty_device_or_error.is_error());
+    return self_tty_device_or_error.release_value();
+}
+
+ErrorOr<NonnullRefPtr<OpenFileDescription>> SelfTTYDevice::open(int options)
+{
+    // Note: If for some odd reason we try to open this device (early on boot?)
+    // while there's no current Process assigned, don't fail and return an error.
+    if (!Process::has_current())
+        return Error::from_errno(ESRCH);
+    auto& current_process = Process::current();
+    RefPtr<TTY> tty = current_process.tty();
+    if (!tty)
+        return Error::from_errno(ENXIO);
+    auto description = TRY(OpenFileDescription::try_create(*tty));
+    description->set_rw_mode(options);
+    description->set_file_flags(options);
+    return description;
+}
+
+bool SelfTTYDevice::can_read(OpenFileDescription const&, u64) const
+{
+    VERIFY_NOT_REACHED();
+}
+
+bool SelfTTYDevice::can_write(OpenFileDescription const&, u64) const
+{
+    VERIFY_NOT_REACHED();
+}
+
+ErrorOr<size_t> SelfTTYDevice::read(OpenFileDescription&, u64, UserOrKernelBuffer&, size_t)
+{
+    VERIFY_NOT_REACHED();
+}
+
+ErrorOr<size_t> SelfTTYDevice::write(OpenFileDescription&, u64, UserOrKernelBuffer const&, size_t)
+{
+    VERIFY_NOT_REACHED();
+}
+
+UNMAP_AFTER_INIT SelfTTYDevice::SelfTTYDevice()
+    : CharacterDevice(5, 0)
+{
+}
+
+UNMAP_AFTER_INIT SelfTTYDevice::~SelfTTYDevice()
+{
+}
+
+}

+ 32 - 0
Kernel/Devices/SelfTTYDevice.h

@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2022, Liav A. <liavalb@hotmail.co.il>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#pragma once
+
+#include <Kernel/Devices/CharacterDevice.h>
+
+namespace Kernel {
+
+class SelfTTYDevice final : public CharacterDevice {
+    friend class DeviceManagement;
+
+public:
+    static NonnullRefPtr<SelfTTYDevice> must_create();
+    virtual ~SelfTTYDevice() override;
+
+private:
+    SelfTTYDevice();
+
+    // ^CharacterDevice
+    virtual ErrorOr<NonnullRefPtr<OpenFileDescription>> open(int options) override;
+    virtual ErrorOr<size_t> read(OpenFileDescription&, u64, UserOrKernelBuffer&, size_t) override;
+    virtual ErrorOr<size_t> write(OpenFileDescription&, u64, UserOrKernelBuffer const&, size_t) override;
+    virtual bool can_read(OpenFileDescription const&, u64) const override;
+    virtual bool can_write(OpenFileDescription const&, u64) const override;
+    virtual StringView class_name() const override { return "SelfTTYDevice"sv; }
+};
+
+}

+ 2 - 0
Kernel/init.cpp

@@ -23,6 +23,7 @@
 #include <Kernel/Devices/NullDevice.h>
 #include <Kernel/Devices/PCISerialDevice.h>
 #include <Kernel/Devices/RandomDevice.h>
+#include <Kernel/Devices/SelfTTYDevice.h>
 #include <Kernel/Devices/SerialDevice.h>
 #include <Kernel/Devices/VMWareBackdoor.h>
 #include <Kernel/Devices/ZeroDevice.h>
@@ -348,6 +349,7 @@ void init_stage2(void*)
     (void)ZeroDevice::must_create().leak_ref();
     (void)FullDevice::must_create().leak_ref();
     (void)RandomDevice::must_create().leak_ref();
+    (void)SelfTTYDevice::must_create().leak_ref();
     PTYMultiplexer::initialize();
 
     AudioManagement::the().initialize();