Kernel: Make pseudo terminals not overwrite old data
If pseudo terminal buffer was filled, old implementation would overwrite old data. This is bad if producer is capable of producing more data than consumer can handle.
This commit is contained in:
parent
73f9de6635
commit
9f4cb5c4dd
|
@ -20,7 +20,7 @@ namespace Kernel
|
|||
|
||||
BAN::ErrorOr<BAN::String> ptsname();
|
||||
|
||||
void putchar(uint8_t ch);
|
||||
bool putchar(uint8_t ch);
|
||||
|
||||
protected:
|
||||
BAN::ErrorOr<size_t> 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<long> ioctl_impl(int, void*) override;
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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<size_t> read_impl(off_t, BAN::ByteSpan) override;
|
||||
virtual BAN::ErrorOr<size_t> write_impl(off_t, BAN::ConstByteSpan) override;
|
||||
|
||||
private:
|
||||
void putchar(uint8_t ch);
|
||||
bool putchar(uint8_t ch);
|
||||
void do_backspace();
|
||||
|
||||
protected:
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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<uint8_t*>(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<uint8_t*>(m_buffer->vaddr())[(m_buffer_tail + m_buffer_size) % m_buffer->size()] = ch;
|
||||
m_buffer_size++;
|
||||
|
||||
m_buffer_blocker.unblock();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
BAN::ErrorOr<size_t> 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<long> PseudoTerminalSlave::ioctl_impl(int request, void* argument)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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<size_t> TTY::read_impl(off_t, BAN::ByteSpan buffer)
|
||||
|
@ -365,10 +366,12 @@ namespace Kernel
|
|||
BAN::ErrorOr<size_t> 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)
|
||||
|
|
|
@ -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()
|
||||
|
|
Loading…
Reference in New Issue