diff options
-rw-r--r-- | Kernel/Makefile | 1 | ||||
-rw-r--r-- | Kernel/MasterPTY.h | 2 | ||||
-rw-r--r-- | Kernel/PTYMultiplexer.cpp | 27 | ||||
-rw-r--r-- | Kernel/PTYMultiplexer.h | 24 | ||||
-rw-r--r-- | Kernel/Process.cpp | 7 | ||||
-rw-r--r-- | Kernel/SlavePTY.h | 2 | ||||
-rw-r--r-- | Kernel/init.cpp | 12 | ||||
-rwxr-xr-x | Kernel/sync.sh | 1 | ||||
-rw-r--r-- | Terminal/main.cpp | 20 | ||||
-rw-r--r-- | VirtualFileSystem/CharacterDevice.cpp | 5 | ||||
-rw-r--r-- | VirtualFileSystem/CharacterDevice.h | 2 | ||||
-rw-r--r-- | VirtualFileSystem/VirtualFileSystem.cpp | 7 | ||||
-rw-r--r-- | VirtualFileSystem/VirtualFileSystem.h | 2 |
13 files changed, 75 insertions, 37 deletions
diff --git a/Kernel/Makefile b/Kernel/Makefile index 0854940359..149cffa46c 100644 --- a/Kernel/Makefile +++ b/Kernel/Makefile @@ -19,6 +19,7 @@ KERNEL_OBJS = \ ProcFileSystem.o \ RTC.o \ TTY.o \ + PTYMultiplexer.o \ MasterPTY.o \ SlavePTY.o \ VirtualConsole.o \ diff --git a/Kernel/MasterPTY.h b/Kernel/MasterPTY.h index 0837e250a4..aa4a27daf0 100644 --- a/Kernel/MasterPTY.h +++ b/Kernel/MasterPTY.h @@ -6,7 +6,6 @@ class SlavePTY; class MasterPTY final : public CharacterDevice { - AK_MAKE_ETERNAL public: explicit MasterPTY(unsigned index); virtual ~MasterPTY() override; @@ -17,6 +16,7 @@ public: virtual bool can_write(Process&) const override; virtual bool is_master_pty() const override { return true; } + unsigned index() const { return m_index; } String pts_name() const; void on_slave_write(const byte*, size_t); diff --git a/Kernel/PTYMultiplexer.cpp b/Kernel/PTYMultiplexer.cpp new file mode 100644 index 0000000000..26403e898c --- /dev/null +++ b/Kernel/PTYMultiplexer.cpp @@ -0,0 +1,27 @@ +#include "PTYMultiplexer.h" +#include "MasterPTY.h" +#include <LibC/errno_numbers.h> + +PTYMultiplexer::PTYMultiplexer() + : CharacterDevice(5, 2) +{ + m_freelist.ensureCapacity(4); + for (int i = 4; i > 0; --i) + m_freelist.unchecked_append(adopt(*new MasterPTY(i - 1))); +} + +PTYMultiplexer::~PTYMultiplexer() +{ +} + +RetainPtr<FileDescriptor> PTYMultiplexer::open(int& error, int options) +{ + LOCKER(m_lock); + if (m_freelist.is_empty()) { + error = -EBUSY; + return nullptr; + } + auto master = m_freelist.takeLast(); + dbgprintf("PTYMultiplexer::open: Vending master %u\n", master->index()); + return VFS::the().open(move(master), error, options); +} diff --git a/Kernel/PTYMultiplexer.h b/Kernel/PTYMultiplexer.h new file mode 100644 index 0000000000..4646fc7f05 --- /dev/null +++ b/Kernel/PTYMultiplexer.h @@ -0,0 +1,24 @@ +#pragma once + +#include <VirtualFileSystem/CharacterDevice.h> +#include <AK/Lock.h> + +class MasterPTY; + +class PTYMultiplexer final : public CharacterDevice { + AK_MAKE_ETERNAL +public: + PTYMultiplexer(); + virtual ~PTYMultiplexer() override; + + // ^CharacterDevice + virtual RetainPtr<FileDescriptor> open(int& error, int options) override; + virtual ssize_t read(Process&, byte*, size_t) override { return 0; } + virtual ssize_t write(Process&, const byte*, size_t) override { return 0; } + virtual bool can_read(Process&) const override { return true; } + virtual bool can_write(Process&) const override { return true; } + +private: + SpinLock m_lock; + Vector<RetainPtr<MasterPTY>> m_freelist; +}; diff --git a/Kernel/Process.cpp b/Kernel/Process.cpp index dbc9f56ab8..8b7bd457ac 100644 --- a/Kernel/Process.cpp +++ b/Kernel/Process.cpp @@ -617,9 +617,10 @@ Process::Process(String&& name, uid_t uid, gid_t gid, pid_t ppid, RingLevel ring } else { m_fds.resize(m_max_open_file_descriptors); if (tty) { - m_fds[0].set(tty->open(O_RDONLY)); - m_fds[1].set(tty->open(O_WRONLY)); - m_fds[2].set(tty->open(O_WRONLY)); + int error; + m_fds[0].set(tty->open(error, O_RDONLY)); + m_fds[1].set(tty->open(error, O_WRONLY)); + m_fds[2].set(tty->open(error, O_WRONLY)); } } diff --git a/Kernel/SlavePTY.h b/Kernel/SlavePTY.h index 773dcee6b4..1b01219349 100644 --- a/Kernel/SlavePTY.h +++ b/Kernel/SlavePTY.h @@ -5,13 +5,13 @@ class MasterPTY; class SlavePTY final : public TTY { - AK_MAKE_ETERNAL public: virtual ~SlavePTY() override; virtual String tty_name() const override; void on_master_write(const byte*, size_t); + unsigned index() const { return m_index; } protected: virtual void on_tty_write(const byte*, size_t) override; diff --git a/Kernel/init.cpp b/Kernel/init.cpp index 2348d53b88..52a942ac8d 100644 --- a/Kernel/init.cpp +++ b/Kernel/init.cpp @@ -22,7 +22,7 @@ #include "VirtualConsole.h" #include "Scheduler.h" #include "PS2MouseDevice.h" -#include "MasterPTY.h" +#include "PTYMultiplexer.h" #define SPAWN_GUI_TEST_APP //#define SPAWN_MULTIPLE_SHELLS @@ -37,10 +37,6 @@ VirtualConsole* tty3; Keyboard* keyboard; PS2MouseDevice* ps2mouse; GUIEventDevice* gui_event_device; -MasterPTY* ptm0; -MasterPTY* ptm1; -MasterPTY* ptm2; -MasterPTY* ptm3; #ifdef STRESS_TEST_SPAWNING static void spawn_stress() NORETURN; @@ -80,10 +76,8 @@ static void init_stage2() auto dev_random = make<RandomDevice>(); vfs->register_character_device(*dev_random); - VFS::the().register_character_device(*new MasterPTY(0)); - VFS::the().register_character_device(*new MasterPTY(1)); - VFS::the().register_character_device(*new MasterPTY(2)); - VFS::the().register_character_device(*new MasterPTY(3)); + auto dev_ptmx = make<PTYMultiplexer>(); + vfs->register_character_device(*dev_ptmx); vfs->register_character_device(*keyboard); vfs->register_character_device(*ps2mouse); diff --git a/Kernel/sync.sh b/Kernel/sync.sh index 0aa9cf6e98..85e619b0cc 100755 --- a/Kernel/sync.sh +++ b/Kernel/sync.sh @@ -9,6 +9,7 @@ mknod mnt/dev/tty1 c 4 1 mknod mnt/dev/tty2 c 4 2 mknod mnt/dev/tty3 c 4 3 mknod mnt/dev/psaux c 10 1 +mknod mnt/dev/ptmx c 5 2 mknod mnt/dev/ptm0 c 10 0 mknod mnt/dev/ptm1 c 10 1 mknod mnt/dev/ptm2 c 10 2 diff --git a/Terminal/main.cpp b/Terminal/main.cpp index 90b0cb23e0..3d1f1decc3 100644 --- a/Terminal/main.cpp +++ b/Terminal/main.cpp @@ -59,23 +59,13 @@ static int max(int a, int b) return a > b ? a : b; } -static int open_ptm() -{ - char buf[32]; - for (unsigned i = 0; i < 4; ++i) { - sprintf(buf, "/dev/ptm%u", i); - int fd = open(buf, O_RDWR); - if (fd) - return fd; - } - dbgprintf("No master PTY available :(\n"); - exit(1); - return -1; -} - int main(int, char**) { - int ptm_fd = open_ptm(); + int ptm_fd = open("/dev/ptmx", O_RDWR); + if (ptm_fd < 0) { + perror("open(ptmx)"); + return 1; + } make_shell(ptm_fd); diff --git a/VirtualFileSystem/CharacterDevice.cpp b/VirtualFileSystem/CharacterDevice.cpp index 61150da2e9..b76e6caba4 100644 --- a/VirtualFileSystem/CharacterDevice.cpp +++ b/VirtualFileSystem/CharacterDevice.cpp @@ -3,12 +3,11 @@ CharacterDevice::~CharacterDevice() { - ASSERT_NOT_REACHED(); } -RetainPtr<FileDescriptor> CharacterDevice::open(int options) +RetainPtr<FileDescriptor> CharacterDevice::open(int& error, int options) { - return VFS::the().open(*this, options); + return VFS::the().open(*this, error, options); } int CharacterDevice::ioctl(Process&, unsigned, unsigned) diff --git a/VirtualFileSystem/CharacterDevice.h b/VirtualFileSystem/CharacterDevice.h index 58df4618ab..92c29ed2cd 100644 --- a/VirtualFileSystem/CharacterDevice.h +++ b/VirtualFileSystem/CharacterDevice.h @@ -13,7 +13,7 @@ public: InodeMetadata metadata() const { return { }; } - RetainPtr<FileDescriptor> open(int options); + virtual RetainPtr<FileDescriptor> open(int& error, int options); virtual bool can_read(Process&) const = 0; virtual bool can_write(Process&) const = 0; diff --git a/VirtualFileSystem/VirtualFileSystem.cpp b/VirtualFileSystem/VirtualFileSystem.cpp index 3700ea332a..957c39421c 100644 --- a/VirtualFileSystem/VirtualFileSystem.cpp +++ b/VirtualFileSystem/VirtualFileSystem.cpp @@ -128,11 +128,12 @@ void VFS::traverse_directory_inode(Inode& dir_inode, Function<bool(const FS::Dir }); } -RetainPtr<FileDescriptor> VFS::open(CharacterDevice& device, int options) +RetainPtr<FileDescriptor> VFS::open(RetainPtr<CharacterDevice>&& device, int& error, int options) { // FIXME: Respect options. (void) options; - return FileDescriptor::create(device); + (void) error; + return FileDescriptor::create(move(device)); } RetainPtr<FileDescriptor> VFS::open(const String& path, int& error, int options, InodeIdentifier base) @@ -148,7 +149,7 @@ RetainPtr<FileDescriptor> VFS::open(const String& path, int& error, int options, kprintf("VFS::open: no such character device %u,%u\n", metadata.majorDevice, metadata.minorDevice); return nullptr; } - return FileDescriptor::create((*it).value); + return (*it).value->open(error, options); } return FileDescriptor::create(move(inode)); } diff --git a/VirtualFileSystem/VirtualFileSystem.h b/VirtualFileSystem/VirtualFileSystem.h index 86a19e62f5..4472eb5e34 100644 --- a/VirtualFileSystem/VirtualFileSystem.h +++ b/VirtualFileSystem/VirtualFileSystem.h @@ -63,7 +63,7 @@ public: bool mount_root(RetainPtr<FS>&&); bool mount(RetainPtr<FS>&&, const String& path); - RetainPtr<FileDescriptor> open(CharacterDevice&, int options); + RetainPtr<FileDescriptor> open(RetainPtr<CharacterDevice>&&, int& error, int options); RetainPtr<FileDescriptor> open(const String& path, int& error, int options = 0, InodeIdentifier base = InodeIdentifier()); RetainPtr<FileDescriptor> create(const String& path, InodeIdentifier base, int& error); bool mkdir(const String& path, mode_t mode, InodeIdentifier base, int& error); |