diff options
24 files changed, 70 insertions, 52 deletions
diff --git a/Kernel/Devices/BlockDevice.h b/Kernel/Devices/BlockDevice.h index afc1a82929..1fdcf21197 100644 --- a/Kernel/Devices/BlockDevice.h +++ b/Kernel/Devices/BlockDevice.h @@ -64,7 +64,7 @@ public: virtual void start_request(AsyncBlockDeviceRequest&) = 0; protected: - BlockDevice(unsigned major, unsigned minor, size_t block_size = PAGE_SIZE) + BlockDevice(MajorNumber major, MinorNumber minor, size_t block_size = PAGE_SIZE) : Device(major, minor) , m_block_size(block_size) { diff --git a/Kernel/Devices/CharacterDevice.h b/Kernel/Devices/CharacterDevice.h index 289e88ba12..01be6e246d 100644 --- a/Kernel/Devices/CharacterDevice.h +++ b/Kernel/Devices/CharacterDevice.h @@ -15,7 +15,7 @@ public: virtual ~CharacterDevice() override; protected: - CharacterDevice(unsigned major, unsigned minor) + CharacterDevice(MajorNumber major, MinorNumber minor) : Device(major, minor) { } diff --git a/Kernel/Devices/Device.cpp b/Kernel/Devices/Device.cpp index 3e32f85f16..3ab07c5241 100644 --- a/Kernel/Devices/Device.cpp +++ b/Kernel/Devices/Device.cpp @@ -114,7 +114,7 @@ RefPtr<SysFSComponent> SysFSCharacterDevicesDirectory::lookup(StringView name) }); } -Device::Device(unsigned major, unsigned minor) +Device::Device(MajorNumber major, MinorNumber minor) : m_major(major) , m_minor(minor) { diff --git a/Kernel/Devices/Device.h b/Kernel/Devices/Device.h index 49be585c03..100a8d7a83 100644 --- a/Kernel/Devices/Device.h +++ b/Kernel/Devices/Device.h @@ -20,6 +20,7 @@ #include <AK/HashMap.h> #include <AK/RefPtr.h> #include <Kernel/Devices/AsyncDeviceRequest.h> +#include <Kernel/FileSystem/DeviceFileTypes.h> #include <Kernel/FileSystem/File.h> #include <Kernel/FileSystem/SysFS.h> #include <Kernel/Locking/Mutex.h> @@ -37,8 +38,8 @@ protected: public: virtual ~Device() override; - unsigned major() const { return m_major; } - unsigned minor() const { return m_minor; } + MajorNumber major() const { return m_major; } + MinorNumber minor() const { return m_minor; } virtual ErrorOr<NonnullOwnPtr<KString>> pseudo_path(const OpenFileDescription&) const override; @@ -63,13 +64,13 @@ public: } protected: - Device(unsigned major, unsigned minor); + Device(MajorNumber major, MinorNumber minor); void set_uid(UserID uid) { m_uid = uid; } void set_gid(GroupID gid) { m_gid = gid; } private: - unsigned m_major { 0 }; - unsigned m_minor { 0 }; + MajorNumber m_major { 0 }; + MinorNumber m_minor { 0 }; UserID m_uid { 0 }; GroupID m_gid { 0 }; diff --git a/Kernel/Devices/DeviceManagement.cpp b/Kernel/Devices/DeviceManagement.cpp index 1b0bd26a45..5f68d1cfb4 100644 --- a/Kernel/Devices/DeviceManagement.cpp +++ b/Kernel/Devices/DeviceManagement.cpp @@ -42,10 +42,10 @@ DeviceManagement& DeviceManagement::the() return *s_the; } -Device* DeviceManagement::get_device(unsigned major, unsigned minor) +Device* DeviceManagement::get_device(MajorNumber major, MinorNumber minor) { return m_devices.with_exclusive([&](auto& map) -> Device* { - auto it = map.find(encoded_device(major, minor)); + auto it = map.find(encoded_device(major.value(), minor.value())); if (it == map.end()) return nullptr; return it->value; @@ -54,7 +54,7 @@ Device* DeviceManagement::get_device(unsigned major, unsigned minor) void DeviceManagement::before_device_removal(Badge<Device>, Device& device) { - u32 device_id = encoded_device(device.major(), device.minor()); + u64 device_id = encoded_device(device.major(), device.minor()); m_devices.with_exclusive([&](auto& map) -> void { VERIFY(map.contains(device_id)); map.remove(encoded_device(device.major(), device.minor())); @@ -63,7 +63,7 @@ void DeviceManagement::before_device_removal(Badge<Device>, Device& device) void DeviceManagement::after_inserting_device(Badge<Device>, Device& device) { - u32 device_id = encoded_device(device.major(), device.minor()); + u64 device_id = encoded_device(device.major(), device.minor()); m_devices.with_exclusive([&](auto& map) -> void { if (map.contains(device_id)) { dbgln("Already registered {},{}: {}", device.major(), device.minor(), device.class_name()); diff --git a/Kernel/Devices/DeviceManagement.h b/Kernel/Devices/DeviceManagement.h index 36069dfd66..9055ce126e 100644 --- a/Kernel/Devices/DeviceManagement.h +++ b/Kernel/Devices/DeviceManagement.h @@ -42,7 +42,7 @@ public: void before_device_removal(Badge<Device>, Device&); void for_each(Function<void(Device&)>); - Device* get_device(unsigned major, unsigned minor); + Device* get_device(MajorNumber major, MinorNumber minor); NullDevice const& null_device() const; NullDevice& null_device(); @@ -63,7 +63,7 @@ private: RefPtr<ConsoleDevice> m_console_device; // FIXME: Once we have a singleton for managing many sound cards, remove this from here NonnullRefPtrVector<CharacterDevice, 1> m_audio_devices; - MutexProtected<HashMap<u32, Device*>> m_devices; + MutexProtected<HashMap<u64, Device*>> m_devices; }; } diff --git a/Kernel/Devices/HID/HIDDevice.h b/Kernel/Devices/HID/HIDDevice.h index dc2137ac02..72d244650c 100644 --- a/Kernel/Devices/HID/HIDDevice.h +++ b/Kernel/Devices/HID/HIDDevice.h @@ -23,7 +23,7 @@ public: virtual void enable_interrupts() = 0; protected: - HIDDevice(unsigned major, unsigned minor) + HIDDevice(MajorNumber major, MinorNumber minor) : CharacterDevice(major, minor) { } diff --git a/Kernel/FileSystem/DevTmpFS.cpp b/Kernel/FileSystem/DevTmpFS.cpp index 26cb558b2d..420ccf4ca3 100644 --- a/Kernel/FileSystem/DevTmpFS.cpp +++ b/Kernel/FileSystem/DevTmpFS.cpp @@ -48,7 +48,7 @@ DevTmpFSInode::DevTmpFSInode(DevTmpFS& fs) { } -DevTmpFSInode::DevTmpFSInode(DevTmpFS& fs, unsigned major_number, unsigned minor_number) +DevTmpFSInode::DevTmpFSInode(DevTmpFS& fs, MajorNumber major_number, MinorNumber minor_number) : Inode(fs, fs.allocate_inode_index()) , m_major_number(major_number) , m_minor_number(minor_number) @@ -263,8 +263,8 @@ ErrorOr<NonnullRefPtr<Inode>> DevTmpFSDirectoryInode::create_child(StringView na } if (metadata.is_device()) { auto name_kstring = TRY(KString::try_create(name)); - unsigned major = major_from_encoded_device(device_mode); - unsigned minor = minor_from_encoded_device(device_mode); + auto major = major_from_encoded_device(device_mode); + auto minor = minor_from_encoded_device(device_mode); auto new_device_inode = TRY(adopt_nonnull_ref_or_enomem(new (nothrow) DevTmpFSDeviceInode(fs(), major, minor, is_block_device(mode), move(name_kstring)))); TRY(new_device_inode->chmod(mode)); m_nodes.append(*new_device_inode); @@ -298,7 +298,7 @@ ErrorOr<void> DevTmpFSRootDirectoryInode::chown(UserID, GroupID) return EPERM; } -DevTmpFSDeviceInode::DevTmpFSDeviceInode(DevTmpFS& fs, unsigned major_number, unsigned minor_number, bool block_device, NonnullOwnPtr<KString> name) +DevTmpFSDeviceInode::DevTmpFSDeviceInode(DevTmpFS& fs, MajorNumber major_number, MinorNumber minor_number, bool block_device, NonnullOwnPtr<KString> name) : DevTmpFSInode(fs, major_number, minor_number) , m_name(move(name)) , m_block_device(block_device) diff --git a/Kernel/FileSystem/DevTmpFS.h b/Kernel/FileSystem/DevTmpFS.h index 1c8599461b..c3d872fc4a 100644 --- a/Kernel/FileSystem/DevTmpFS.h +++ b/Kernel/FileSystem/DevTmpFS.h @@ -47,7 +47,7 @@ public: protected: explicit DevTmpFSInode(DevTmpFS&); - DevTmpFSInode(DevTmpFS&, unsigned, unsigned); + DevTmpFSInode(DevTmpFS&, MajorNumber, MinorNumber); virtual ErrorOr<size_t> read_bytes(off_t, size_t, UserOrKernelBuffer& buffer, OpenFileDescription*) const override; virtual ErrorOr<void> traverse_as_directory(Function<ErrorOr<void>(FileSystem::DirectoryEntryView const&)>) const override; virtual ErrorOr<NonnullRefPtr<Inode>> lookup(StringView name) override; @@ -64,8 +64,8 @@ protected: mode_t m_mode { 0600 }; UserID m_uid { 0 }; GroupID m_gid { 0 }; - const unsigned m_major_number { 0 }; - const unsigned m_minor_number { 0 }; + const MajorNumber m_major_number { 0 }; + const MinorNumber m_minor_number { 0 }; enum class Type { BlockDevice, @@ -90,7 +90,7 @@ public: virtual ~DevTmpFSDeviceInode() override; private: - DevTmpFSDeviceInode(DevTmpFS&, unsigned, unsigned, bool, NonnullOwnPtr<KString> name); + DevTmpFSDeviceInode(DevTmpFS&, MajorNumber, MinorNumber, bool, NonnullOwnPtr<KString> name); // ^DevTmpFSInode virtual Type node_type() const override { return m_block_device ? Type::BlockDevice : Type::CharacterDevice; } diff --git a/Kernel/FileSystem/DeviceFileTypes.h b/Kernel/FileSystem/DeviceFileTypes.h new file mode 100644 index 0000000000..aba01e973b --- /dev/null +++ b/Kernel/FileSystem/DeviceFileTypes.h @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2021, Liav A. <liavalb@hotmail.co.il> + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include <AK/Types.h> + +namespace Kernel { + +TYPEDEF_DISTINCT_ORDERED_ID(unsigned, MajorNumber); +TYPEDEF_DISTINCT_ORDERED_ID(unsigned, MinorNumber); + +} diff --git a/Kernel/FileSystem/InodeMetadata.h b/Kernel/FileSystem/InodeMetadata.h index 95bfba8367..1dc23b6d72 100644 --- a/Kernel/FileSystem/InodeMetadata.h +++ b/Kernel/FileSystem/InodeMetadata.h @@ -8,6 +8,7 @@ #include <AK/Error.h> #include <AK/Span.h> +#include <Kernel/FileSystem/DeviceFileTypes.h> #include <Kernel/FileSystem/InodeIdentifier.h> #include <Kernel/Forward.h> #include <Kernel/UnixTypes.h> @@ -16,12 +17,12 @@ namespace Kernel { class Process; -constexpr u32 encoded_device(unsigned major, unsigned minor) +constexpr u64 encoded_device(MajorNumber major, MinorNumber minor) { - return (minor & 0xff) | (major << 8) | ((minor & ~0xff) << 12); + return (minor.value() & 0xff) | (major.value() << 8) | ((minor.value() & ~0xff) << 12); } -static inline unsigned int major_from_encoded_device(dev_t dev) { return (dev & 0xfff00u) >> 8u; } -static inline unsigned int minor_from_encoded_device(dev_t dev) { return (dev & 0xffu) | ((dev >> 12u) & 0xfff00u); } +static inline MajorNumber major_from_encoded_device(dev_t dev) { return (dev & 0xfff00u) >> 8u; } +static inline MinorNumber minor_from_encoded_device(dev_t dev) { return (dev & 0xffu) | ((dev >> 12u) & 0xfff00u); } inline bool is_directory(mode_t mode) { return (mode & S_IFMT) == S_IFDIR; } inline bool is_character_device(mode_t mode) { return (mode & S_IFMT) == S_IFCHR; } @@ -122,8 +123,8 @@ struct InodeMetadata { time_t dtime { 0 }; blkcnt_t block_count { 0 }; blksize_t block_size { 0 }; - unsigned major_device { 0 }; - unsigned minor_device { 0 }; + MajorNumber major_device { 0 }; + MinorNumber minor_device { 0 }; }; } diff --git a/Kernel/GlobalProcessExposed.cpp b/Kernel/GlobalProcessExposed.cpp index 2733e9537c..83517a49fe 100644 --- a/Kernel/GlobalProcessExposed.cpp +++ b/Kernel/GlobalProcessExposed.cpp @@ -681,8 +681,8 @@ private: JsonArraySerializer array { builder }; DeviceManagement::the().for_each([&array](auto& device) { auto obj = array.add_object(); - obj.add("major", device.major()); - obj.add("minor", device.minor()); + obj.add("major", device.major().value()); + obj.add("minor", device.minor().value()); obj.add("class_name", device.class_name()); if (device.is_block_device()) diff --git a/Kernel/Storage/ATA/ATADevice.cpp b/Kernel/Storage/ATA/ATADevice.cpp index 7e24a0cc68..c40f5b4eec 100644 --- a/Kernel/Storage/ATA/ATADevice.cpp +++ b/Kernel/Storage/ATA/ATADevice.cpp @@ -13,8 +13,8 @@ namespace Kernel { -ATADevice::ATADevice(const ATAController& controller, ATADevice::Address ata_address, unsigned minor_number, u16 capabilities, u16 logical_sector_size, u64 max_addressable_block, NonnullOwnPtr<KString> early_storage_name) - : StorageDevice(StorageManagement::major_number(), minor_number, logical_sector_size, max_addressable_block, move(early_storage_name)) +ATADevice::ATADevice(const ATAController& controller, ATADevice::Address ata_address, MinorNumber minor_number, u16 capabilities, u16 logical_sector_size, u64 max_addressable_block, NonnullOwnPtr<KString> early_storage_name) + : StorageDevice(StorageManagement::storage_type_major_number(), minor_number, logical_sector_size, max_addressable_block, move(early_storage_name)) , m_controller(controller) , m_ata_address(ata_address) , m_capabilities(capabilities) diff --git a/Kernel/Storage/ATA/ATADevice.h b/Kernel/Storage/ATA/ATADevice.h index 9c32d2d110..e469dcfe8c 100644 --- a/Kernel/Storage/ATA/ATADevice.h +++ b/Kernel/Storage/ATA/ATADevice.h @@ -36,7 +36,7 @@ public: const Address& ata_address() const { return m_ata_address; } protected: - ATADevice(const ATAController&, Address, unsigned, u16, u16, u64, NonnullOwnPtr<KString>); + ATADevice(const ATAController&, Address, MinorNumber, u16, u16, u64, NonnullOwnPtr<KString>); WeakPtr<ATAController> m_controller; const Address m_ata_address; diff --git a/Kernel/Storage/ATA/ATADiskDevice.cpp b/Kernel/Storage/ATA/ATADiskDevice.cpp index 3d7af895be..09e867164f 100644 --- a/Kernel/Storage/ATA/ATADiskDevice.cpp +++ b/Kernel/Storage/ATA/ATADiskDevice.cpp @@ -16,10 +16,10 @@ namespace Kernel { NonnullRefPtr<ATADiskDevice> ATADiskDevice::create(const ATAController& controller, ATADevice::Address ata_address, u16 capabilities, u16 logical_sector_size, u64 max_addressable_block) { - auto minor_device_number = StorageManagement::minor_number(); + auto minor_device_number = StorageManagement::generate_storage_minor_number(); // FIXME: We need a way of formatting strings with KString. - auto device_name = String::formatted("hd{:c}", 'a' + minor_device_number); + auto device_name = String::formatted("hd{:c}", 'a' + minor_device_number.value()); auto device_name_kstring = KString::must_create(device_name.view()); auto disk_device_or_error = DeviceManagement::try_create_device<ATADiskDevice>(controller, ata_address, minor_device_number, capabilities, logical_sector_size, max_addressable_block, move(device_name_kstring)); @@ -28,7 +28,7 @@ NonnullRefPtr<ATADiskDevice> ATADiskDevice::create(const ATAController& controll return disk_device_or_error.release_value(); } -ATADiskDevice::ATADiskDevice(const ATAController& controller, ATADevice::Address ata_address, unsigned minor_number, u16 capabilities, u16 logical_sector_size, u64 max_addressable_block, NonnullOwnPtr<KString> early_storage_name) +ATADiskDevice::ATADiskDevice(const ATAController& controller, ATADevice::Address ata_address, MinorNumber minor_number, u16 capabilities, u16 logical_sector_size, u64 max_addressable_block, NonnullOwnPtr<KString> early_storage_name) : ATADevice(controller, ata_address, minor_number, capabilities, logical_sector_size, max_addressable_block, move(early_storage_name)) { } diff --git a/Kernel/Storage/ATA/ATADiskDevice.h b/Kernel/Storage/ATA/ATADiskDevice.h index 6a5492f838..c71672321e 100644 --- a/Kernel/Storage/ATA/ATADiskDevice.h +++ b/Kernel/Storage/ATA/ATADiskDevice.h @@ -26,7 +26,7 @@ public: virtual CommandSet command_set() const override { return CommandSet::ATA; } private: - ATADiskDevice(const ATAController&, Address, unsigned, u16, u16, u64, NonnullOwnPtr<KString>); + ATADiskDevice(const ATAController&, Address, MinorNumber, u16, u16, u64, NonnullOwnPtr<KString>); // ^DiskDevice virtual StringView class_name() const override; diff --git a/Kernel/Storage/ATA/ATAPIDiscDevice.cpp b/Kernel/Storage/ATA/ATAPIDiscDevice.cpp index 7c60f54a14..984312bf08 100644 --- a/Kernel/Storage/ATA/ATAPIDiscDevice.cpp +++ b/Kernel/Storage/ATA/ATAPIDiscDevice.cpp @@ -16,19 +16,19 @@ namespace Kernel { NonnullRefPtr<ATAPIDiscDevice> ATAPIDiscDevice::create(const ATAController& controller, ATADevice::Address ata_address, u16 capabilities, u64 max_addressable_block) { - auto minor_device_number = StorageManagement::minor_number(); + auto minor_device_number = StorageManagement::generate_storage_minor_number(); // FIXME: We need a way of formatting strings with KString. - auto device_name = String::formatted("hd{:c}", 'a' + minor_device_number); + auto device_name = String::formatted("hd{:c}", 'a' + minor_device_number.value()); auto device_name_kstring = KString::must_create(device_name.view()); - auto disc_device_or_error = DeviceManagement::try_create_device<ATAPIDiscDevice>(controller, ata_address, minor_device_number, capabilities, max_addressable_block, move(device_name_kstring)); + auto disc_device_or_error = DeviceManagement::try_create_device<ATAPIDiscDevice>(controller, ata_address, minor_device_number.value(), capabilities, max_addressable_block, move(device_name_kstring)); // FIXME: Find a way to propagate errors VERIFY(!disc_device_or_error.is_error()); return disc_device_or_error.release_value(); } -ATAPIDiscDevice::ATAPIDiscDevice(const ATAController& controller, ATADevice::Address ata_address, unsigned minor_number, u16 capabilities, u64 max_addressable_block, NonnullOwnPtr<KString> early_storage_name) +ATAPIDiscDevice::ATAPIDiscDevice(const ATAController& controller, ATADevice::Address ata_address, MinorNumber minor_number, u16 capabilities, u64 max_addressable_block, NonnullOwnPtr<KString> early_storage_name) : ATADevice(controller, ata_address, minor_number, capabilities, 0, max_addressable_block, move(early_storage_name)) { } diff --git a/Kernel/Storage/ATA/ATAPIDiscDevice.h b/Kernel/Storage/ATA/ATAPIDiscDevice.h index 0556fb97d1..12a18bde33 100644 --- a/Kernel/Storage/ATA/ATAPIDiscDevice.h +++ b/Kernel/Storage/ATA/ATAPIDiscDevice.h @@ -26,7 +26,7 @@ public: virtual CommandSet command_set() const override { return CommandSet::SCSI; } private: - ATAPIDiscDevice(const ATAController&, Address, unsigned, u16, u64, NonnullOwnPtr<KString>); + ATAPIDiscDevice(const ATAController&, Address, MinorNumber, u16, u64, NonnullOwnPtr<KString>); // ^DiskDevice virtual StringView class_name() const override; diff --git a/Kernel/Storage/StorageDevice.cpp b/Kernel/Storage/StorageDevice.cpp index 52e304e005..dc126b379b 100644 --- a/Kernel/Storage/StorageDevice.cpp +++ b/Kernel/Storage/StorageDevice.cpp @@ -14,7 +14,7 @@ namespace Kernel { -StorageDevice::StorageDevice(int major, int minor, size_t sector_size, u64 max_addressable_block, NonnullOwnPtr<KString> device_name) +StorageDevice::StorageDevice(MajorNumber major, MinorNumber minor, size_t sector_size, u64 max_addressable_block, NonnullOwnPtr<KString> device_name) : BlockDevice(major, minor, sector_size) , m_early_storage_device_name(move(device_name)) , m_max_addressable_block(max_addressable_block) diff --git a/Kernel/Storage/StorageDevice.h b/Kernel/Storage/StorageDevice.h index a34908c6c7..8472009669 100644 --- a/Kernel/Storage/StorageDevice.h +++ b/Kernel/Storage/StorageDevice.h @@ -54,7 +54,7 @@ public: virtual ErrorOr<void> ioctl(OpenFileDescription&, unsigned request, Userspace<void*> arg) final; protected: - StorageDevice(int, int, size_t, u64, NonnullOwnPtr<KString>); + StorageDevice(MajorNumber, MinorNumber, size_t, u64, NonnullOwnPtr<KString>); // ^DiskDevice virtual StringView class_name() const override; diff --git a/Kernel/Storage/StorageManagement.cpp b/Kernel/Storage/StorageManagement.cpp index e14aae4bb7..c64571846e 100644 --- a/Kernel/Storage/StorageManagement.cpp +++ b/Kernel/Storage/StorageManagement.cpp @@ -24,7 +24,7 @@ namespace Kernel { static Singleton<StorageManagement> s_the; -static Atomic<size_t> s_device_minor_number; +static Atomic<u32> s_device_minor_number; static constexpr StringView partition_uuid_prefix = "PARTUUID="sv; @@ -179,11 +179,11 @@ RefPtr<BlockDevice> StorageManagement::boot_block_device() const return m_boot_block_device.strong_ref(); } -int StorageManagement::major_number() +MajorNumber StorageManagement::storage_type_major_number() { return 3; } -int StorageManagement::minor_number() +MinorNumber StorageManagement::generate_storage_minor_number() { auto minor_number = s_device_minor_number.load(); s_device_minor_number++; diff --git a/Kernel/Storage/StorageManagement.h b/Kernel/Storage/StorageManagement.h index 656a5f5a71..131d23b90b 100644 --- a/Kernel/Storage/StorageManagement.h +++ b/Kernel/Storage/StorageManagement.h @@ -29,8 +29,8 @@ public: NonnullRefPtr<FileSystem> root_filesystem() const; - static int major_number(); - static int minor_number(); + static MajorNumber storage_type_major_number(); + static MinorNumber generate_storage_minor_number(); void remove_device(StorageDevice&); diff --git a/Kernel/TTY/TTY.cpp b/Kernel/TTY/TTY.cpp index b5b22ca816..06dce47dc5 100644 --- a/Kernel/TTY/TTY.cpp +++ b/Kernel/TTY/TTY.cpp @@ -19,7 +19,7 @@ namespace Kernel { -TTY::TTY(unsigned major, unsigned minor) +TTY::TTY(MajorNumber major, MinorNumber minor) : CharacterDevice(major, minor) { set_default_termios(); diff --git a/Kernel/TTY/TTY.h b/Kernel/TTY/TTY.h index 897e15b57c..eb1ee2134e 100644 --- a/Kernel/TTY/TTY.h +++ b/Kernel/TTY/TTY.h @@ -53,7 +53,7 @@ protected: virtual ErrorOr<size_t> on_tty_write(const UserOrKernelBuffer&, size_t) = 0; void set_size(unsigned short columns, unsigned short rows); - TTY(unsigned major, unsigned minor); + TTY(MajorNumber major, MinorNumber minor); void emit(u8, bool do_evaluate_block_conditions = false); void echo_with_processing(u8); |