From 0f037167c450edd55769eddbf113244082f54a1b Mon Sep 17 00:00:00 2001 From: JJ Roberts-White Date: Fri, 22 Oct 2021 09:24:39 +1100 Subject: [PATCH] Kernel: Properly destroy PTYs after master is closed. Ensure signal stack alignment. --- Kernel/include/TTY/PTY.h | 4 ++++ Kernel/src/Arch/x86_64/Thread.cpp | 3 ++- Kernel/src/CharacterBuffer.cpp | 6 ++++++ Kernel/src/Device.cpp | 20 +++++--------------- Kernel/src/TTY/PTMX.cpp | 12 ++++++++++++ Kernel/src/TTY/PTY.cpp | 25 +++++++++++++++++++++++++ 6 files changed, 54 insertions(+), 16 deletions(-) diff --git a/Kernel/include/TTY/PTY.h b/Kernel/include/TTY/PTY.h index 8f2eb391..a1a8cff6 100755 --- a/Kernel/include/TTY/PTY.h +++ b/Kernel/include/TTY/PTY.h @@ -38,6 +38,7 @@ class PTMultiplexor final : public Device { static inline PTMultiplexor& Instance() { return *m_instance; } UNIXFileDescriptor* Open(size_t flags) override; + void DestroyPTY(PTY* pt); private: static PTMultiplexor* m_instance; @@ -58,6 +59,8 @@ class PTYDevice : public FsNode { PTYDevice(); + void Close() override; + ssize_t Read(size_t, size_t, uint8_t *) override; ssize_t Write(size_t, size_t, uint8_t *) override; int Ioctl(uint64_t cmd, uint64_t arg) override; @@ -83,6 +86,7 @@ class PTY{ termios tios; PTY(int id); + ~PTY(); inline int GetID() const { return m_id; } diff --git a/Kernel/src/Arch/x86_64/Thread.cpp b/Kernel/src/Arch/x86_64/Thread.cpp index 4c2f33e3..c58bc897 100644 --- a/Kernel/src/Arch/x86_64/Thread.cpp +++ b/Kernel/src/Arch/x86_64/Thread.cpp @@ -163,7 +163,8 @@ void Thread::HandlePendingSignal(RegisterContext* regs) { //uint64_t* stack = reinterpret_cast(regs->rsp - sizeof(ucontext_t)); //ucontext_t* ucontext = reinterpret_cast(stack); - uint64_t* stack = reinterpret_cast(regs->rsp - sizeof(RegisterContext)); + // Ensure stack alignment + uint64_t* stack = reinterpret_cast((regs->rsp & (~0xfULL)) - sizeof(RegisterContext)); *reinterpret_cast(stack) = *regs; *(--stack) = oldSignalMask; diff --git a/Kernel/src/CharacterBuffer.cpp b/Kernel/src/CharacterBuffer.cpp index b8aa230a..1cc48c8d 100755 --- a/Kernel/src/CharacterBuffer.cpp +++ b/Kernel/src/CharacterBuffer.cpp @@ -12,6 +12,12 @@ CharacterBuffer::CharacterBuffer() { lines = 0; } +CharacterBuffer::~CharacterBuffer() { + if(buffer){ + delete buffer; + } +} + ssize_t CharacterBuffer::Write(char* _buffer, size_t size) { if (bufferPos + size > maxBufferSize) { size = maxBufferSize - bufferPos; diff --git a/Kernel/src/Device.cpp b/Kernel/src/Device.cpp index 76de35c0..6e930900 100644 --- a/Kernel/src/Device.cpp +++ b/Kernel/src/Device.cpp @@ -44,8 +44,7 @@ class TTY : public Device { SetDeviceName("Process Terminal"); } - ssize_t Read(size_t, size_t, uint8_t*); - ssize_t Write(size_t, size_t, uint8_t*); + UNIXFileDescriptor* Open(size_t flags) override; }; int Device::nextUnnamedDeviceNumber = 0; @@ -131,23 +130,14 @@ ssize_t URandom::Read(size_t offset, size_t size, uint8_t* buffer) { ssize_t URandom::Write(size_t offset, size_t size, uint8_t* buffer) { return size; } - -ssize_t TTY::Read(size_t offset, size_t size, uint8_t* buffer) { - auto stdin = Scheduler::GetCurrentProcess()->GetFileDescriptor(0); - - if(stdin && stdin->node){ - return fs::Read(stdin->node, offset, size, buffer); - } - return -EBADF; -} - -ssize_t TTY::Write(size_t offset, size_t size, uint8_t* buffer) { +UNIXFileDescriptor* TTY::Open(size_t flags){ auto stdout = Scheduler::GetCurrentProcess()->GetFileDescriptor(1); if(stdout && stdout->node){ - return fs::Write(stdout->node, offset, size, buffer); + return stdout->node->Open(flags); } - return -EBADF; + + return nullptr; } Null null = Null("null"); diff --git a/Kernel/src/TTY/PTMX.cpp b/Kernel/src/TTY/PTMX.cpp index 213b9b34..ca46c52b 100644 --- a/Kernel/src/TTY/PTMX.cpp +++ b/Kernel/src/TTY/PTMX.cpp @@ -66,3 +66,15 @@ UNIXFileDescriptor* PTMultiplexor::Open(size_t flags){ return pty->masterFile.Open(flags); } + +void PTMultiplexor::DestroyPTY(PTY* pt){ + ScopedSpinLock lock(m_ptmxLock); + for(auto it = m_ptList.begin(); it != m_ptList.end(); it++) { + if(*it == pt){ + m_ptList.remove(pt); + delete pt; + + return; + } + } +} diff --git a/Kernel/src/TTY/PTY.cpp b/Kernel/src/TTY/PTY.cpp index 23a50ccc..5fce5b8f 100755 --- a/Kernel/src/TTY/PTY.cpp +++ b/Kernel/src/TTY/PTY.cpp @@ -27,6 +27,14 @@ PTYDevice::PTYDevice() { } +void PTYDevice::Close() { + handleCount--; + + if(handleCount == 0 && device == PTYMasterDevice){ + PTMultiplexor::Instance().DestroyPTY(pty); + } +} + ssize_t PTYDevice::Read(size_t offset, size_t size, uint8_t* buffer) { assert(pty); assert(device == PTYSlaveDevice || device == PTYMasterDevice); @@ -99,6 +107,13 @@ int PTYDevice::Ioctl(uint64_t cmd, uint64_t arg) { assert(pty); switch (cmd) { + case TCGETS: + *((termios*)arg) = pty->tios; + break; + case TCSETS: + pty->tios = *((termios*)arg); + pty->slave.ignoreBackspace = !pty->IsCanonical(); + break; case TIOCGWINSZ: *((winsz*)arg) = pty->wSz; break; @@ -187,6 +202,16 @@ PTY::PTY(int id) : m_id(id) { tios.c_cc[i] = c_cc_default[i]; } +PTY::~PTY(){ + while (m_watchingSlave.get_length()) { + m_watchingSlave.remove_at(0)->Signal(); // Signal all watching + } + + while (m_watchingMaster.get_length()) { + m_watchingMaster.remove_at(0)->Signal(); // Signal all watching + } +} + ssize_t PTY::MasterRead(char* buffer, size_t count) { return master.Read(buffer, count); } ssize_t PTY::SlaveRead(char* buffer, size_t count) {