diff --git a/kernel/include/kernel/Terminal/PseudoTerminal.h b/kernel/include/kernel/Terminal/PseudoTerminal.h index 731ecd45..29d80e82 100644 --- a/kernel/include/kernel/Terminal/PseudoTerminal.h +++ b/kernel/include/kernel/Terminal/PseudoTerminal.h @@ -20,7 +20,7 @@ namespace Kernel BAN::ErrorOr ptsname(); - void putchar(uint8_t ch); + bool putchar(uint8_t ch); protected: BAN::ErrorOr read_impl(off_t, BAN::ByteSpan) override; @@ -61,7 +61,7 @@ namespace Kernel void clear() override; protected: - void putchar_impl(uint8_t ch) override; + bool putchar_impl(uint8_t ch) override; BAN::ErrorOr ioctl_impl(int, void*) override; diff --git a/kernel/include/kernel/Terminal/Serial.h b/kernel/include/kernel/Terminal/Serial.h index 14a80bca..ce1d6f8c 100644 --- a/kernel/include/kernel/Terminal/Serial.h +++ b/kernel/include/kernel/Terminal/Serial.h @@ -53,7 +53,7 @@ namespace Kernel protected: virtual BAN::StringView name() const override { return m_name; } - virtual void putchar_impl(uint8_t) override; + virtual bool putchar_impl(uint8_t) override; private: SerialTTY(Serial); diff --git a/kernel/include/kernel/Terminal/TTY.h b/kernel/include/kernel/Terminal/TTY.h index bf2749b8..d2be6e63 100644 --- a/kernel/include/kernel/Terminal/TTY.h +++ b/kernel/include/kernel/Terminal/TTY.h @@ -58,14 +58,14 @@ namespace Kernel protected: TTY(mode_t mode, uid_t uid, gid_t gid); - virtual void putchar_impl(uint8_t ch) = 0; + virtual bool putchar_impl(uint8_t ch) = 0; virtual void update_cursor() {} virtual BAN::ErrorOr read_impl(off_t, BAN::ByteSpan) override; virtual BAN::ErrorOr write_impl(off_t, BAN::ConstByteSpan) override; private: - void putchar(uint8_t ch); + bool putchar(uint8_t ch); void do_backspace(); protected: diff --git a/kernel/include/kernel/Terminal/VirtualTTY.h b/kernel/include/kernel/Terminal/VirtualTTY.h index f2e40afc..d4f3cf02 100644 --- a/kernel/include/kernel/Terminal/VirtualTTY.h +++ b/kernel/include/kernel/Terminal/VirtualTTY.h @@ -26,7 +26,7 @@ namespace Kernel protected: virtual BAN::StringView name() const override { return m_name; } - virtual void putchar_impl(uint8_t ch) override; + virtual bool putchar_impl(uint8_t ch) override; void update_cursor() override; private: diff --git a/kernel/kernel/Terminal/PseudoTerminal.cpp b/kernel/kernel/Terminal/PseudoTerminal.cpp index 6f2428b4..a6b78ecb 100644 --- a/kernel/kernel/Terminal/PseudoTerminal.cpp +++ b/kernel/kernel/Terminal/PseudoTerminal.cpp @@ -85,16 +85,19 @@ namespace Kernel return BAN::Error::from_errno(ENODEV); } - void PseudoTerminalMaster::putchar(uint8_t ch) + bool PseudoTerminalMaster::putchar(uint8_t ch) { SpinLockGuard _(m_buffer_lock); - reinterpret_cast(m_buffer->vaddr())[(m_buffer_tail + m_buffer_size) % m_buffer->size()] = ch; + if (m_buffer_size >= m_buffer->size()) + return false; - if (m_buffer_size < m_buffer->size()) - m_buffer_size++; - else - m_buffer_tail = (m_buffer_tail + 1) % m_buffer->size(); + reinterpret_cast(m_buffer->vaddr())[(m_buffer_tail + m_buffer_size) % m_buffer->size()] = ch; + m_buffer_size++; + + m_buffer_blocker.unblock(); + + return true; } BAN::ErrorOr PseudoTerminalMaster::read_impl(off_t, BAN::ByteSpan buffer) @@ -166,10 +169,11 @@ namespace Kernel (void)write_impl(0, BAN::ConstByteSpan::from(message)); } - void PseudoTerminalSlave::putchar_impl(uint8_t ch) + bool PseudoTerminalSlave::putchar_impl(uint8_t ch) { if (auto master = m_master.lock()) - master->putchar(ch); + return master->putchar(ch); + return false; } BAN::ErrorOr PseudoTerminalSlave::ioctl_impl(int request, void* argument) diff --git a/kernel/kernel/Terminal/Serial.cpp b/kernel/kernel/Terminal/Serial.cpp index f00bb3d3..bcc68831 100644 --- a/kernel/kernel/Terminal/Serial.cpp +++ b/kernel/kernel/Terminal/Serial.cpp @@ -258,9 +258,10 @@ namespace Kernel return m_serial.height(); } - void SerialTTY::putchar_impl(uint8_t ch) + bool SerialTTY::putchar_impl(uint8_t ch) { m_serial.putchar(ch); + return true; } } diff --git a/kernel/kernel/Terminal/TTY.cpp b/kernel/kernel/Terminal/TTY.cpp index e99b5d78..4f3bcb1b 100644 --- a/kernel/kernel/Terminal/TTY.cpp +++ b/kernel/kernel/Terminal/TTY.cpp @@ -327,11 +327,12 @@ namespace Kernel } } - void TTY::putchar(uint8_t ch) + bool TTY::putchar(uint8_t ch) { SpinLockGuard _(m_write_lock); if (m_tty_ctrl.draw_graphics) - putchar_impl(ch); + return putchar_impl(ch); + return true; } BAN::ErrorOr TTY::read_impl(off_t, BAN::ByteSpan buffer) @@ -365,10 +366,12 @@ namespace Kernel BAN::ErrorOr TTY::write_impl(off_t, BAN::ConstByteSpan buffer) { SpinLockGuard _(m_write_lock); - for (size_t i = 0; i < buffer.size(); i++) - putchar(buffer[i]); + size_t written = 0; + for (; written < buffer.size(); written++) + if (!putchar(buffer[written])) + break; update_cursor(); - return buffer.size(); + return written; } void TTY::putchar_current(uint8_t ch) diff --git a/kernel/kernel/Terminal/VirtualTTY.cpp b/kernel/kernel/Terminal/VirtualTTY.cpp index 4f60d534..f11a2290 100644 --- a/kernel/kernel/Terminal/VirtualTTY.cpp +++ b/kernel/kernel/Terminal/VirtualTTY.cpp @@ -501,7 +501,7 @@ namespace Kernel scroll_if_needed(); } - void VirtualTTY::putchar_impl(uint8_t ch) + bool VirtualTTY::putchar_impl(uint8_t ch) { ASSERT(m_write_lock.current_processor_has_lock()); @@ -531,10 +531,10 @@ namespace Kernel { reset_ansi(); dprintln_if(DEBUG_VTTY, "invalid utf8"); - return; + return true; } m_state = State::WaitingUTF8; - return; + return true; case State::WaitingAnsiEscape: if (ch == CSI) m_state = State::WaitingAnsiCSI; @@ -543,21 +543,21 @@ namespace Kernel reset_ansi(); dprintln_if(DEBUG_VTTY, "unsupported byte after ansi escape {2H}", (uint8_t)ch); } - return; + return true; case State::WaitingAnsiCSI: handle_ansi_csi(ch); - return; + return true; case State::WaitingUTF8: if ((ch & 0xC0) != 0x80) { m_state = State::Normal; dprintln_if(DEBUG_VTTY, "invalid utf8"); - return; + return true; } m_utf8_state.codepoint = (m_utf8_state.codepoint << 6) | (ch & 0x3F); m_utf8_state.bytes_missing--; if (m_utf8_state.bytes_missing) - return; + return true; m_state = State::Normal; codepoint = m_utf8_state.codepoint; break; @@ -566,6 +566,7 @@ namespace Kernel } putcodepoint(codepoint); + return true; } void VirtualTTY::update_cursor()