forked from Bananymous/banan-os
Kernel: Add better termios support
I'm not sure if this is correct but at least it's better than before :)
This commit is contained in:
parent
9b875fb930
commit
8ff9c030bf
|
@ -14,7 +14,7 @@
|
||||||
#define dprintln(...) \
|
#define dprintln(...) \
|
||||||
do { \
|
do { \
|
||||||
BAN::Formatter::print(__debug_putchar, __VA_ARGS__); \
|
BAN::Formatter::print(__debug_putchar, __VA_ARGS__); \
|
||||||
BAN::Formatter::print(__debug_putchar,"\r\n"); \
|
BAN::Formatter::print(__debug_putchar,"\n"); \
|
||||||
fflush(stddbg); \
|
fflush(stddbg); \
|
||||||
} while (false)
|
} while (false)
|
||||||
|
|
||||||
|
@ -22,7 +22,7 @@
|
||||||
do { \
|
do { \
|
||||||
BAN::Formatter::print(__debug_putchar, "\e[33m"); \
|
BAN::Formatter::print(__debug_putchar, "\e[33m"); \
|
||||||
BAN::Formatter::print(__debug_putchar, __VA_ARGS__); \
|
BAN::Formatter::print(__debug_putchar, __VA_ARGS__); \
|
||||||
BAN::Formatter::print(__debug_putchar, "\e[m\r\n"); \
|
BAN::Formatter::print(__debug_putchar, "\e[m\n"); \
|
||||||
fflush(stddbg); \
|
fflush(stddbg); \
|
||||||
} while(false)
|
} while(false)
|
||||||
|
|
||||||
|
@ -30,7 +30,7 @@
|
||||||
do { \
|
do { \
|
||||||
BAN::Formatter::print(__debug_putchar, "\e[31m"); \
|
BAN::Formatter::print(__debug_putchar, "\e[31m"); \
|
||||||
BAN::Formatter::print(__debug_putchar, __VA_ARGS__); \
|
BAN::Formatter::print(__debug_putchar, __VA_ARGS__); \
|
||||||
BAN::Formatter::print(__debug_putchar, "\e[m\r\n"); \
|
BAN::Formatter::print(__debug_putchar, "\e[m\n"); \
|
||||||
fflush(stddbg); \
|
fflush(stddbg); \
|
||||||
} while(false)
|
} while(false)
|
||||||
|
|
||||||
|
|
|
@ -57,7 +57,7 @@ namespace Kernel
|
||||||
virtual bool has_hungup_impl() const override { return false; }
|
virtual bool has_hungup_impl() const override { return false; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
TTY(mode_t mode, uid_t uid, gid_t gid);
|
TTY(termios termios, mode_t mode, uid_t uid, gid_t gid);
|
||||||
|
|
||||||
virtual bool putchar_impl(uint8_t ch) = 0;
|
virtual bool putchar_impl(uint8_t ch) = 0;
|
||||||
virtual void update_cursor() {}
|
virtual void update_cursor() {}
|
||||||
|
|
|
@ -158,7 +158,15 @@ namespace Kernel
|
||||||
}
|
}
|
||||||
|
|
||||||
PseudoTerminalSlave::PseudoTerminalSlave(BAN::String&& name, uint32_t number, mode_t mode, uid_t uid, gid_t gid)
|
PseudoTerminalSlave::PseudoTerminalSlave(BAN::String&& name, uint32_t number, mode_t mode, uid_t uid, gid_t gid)
|
||||||
: TTY(mode, uid, gid)
|
: TTY({
|
||||||
|
.c_iflag = 0,
|
||||||
|
.c_oflag = 0,
|
||||||
|
.c_cflag = CS8,
|
||||||
|
.c_lflag = ECHO | ICANON,
|
||||||
|
.c_cc = {},
|
||||||
|
.c_ospeed = B38400,
|
||||||
|
.c_ispeed = B38400,
|
||||||
|
}, mode, uid, gid)
|
||||||
, m_name(BAN::move(name))
|
, m_name(BAN::move(name))
|
||||||
, m_number(number)
|
, m_number(number)
|
||||||
{}
|
{}
|
||||||
|
|
|
@ -170,7 +170,15 @@ namespace Kernel
|
||||||
}
|
}
|
||||||
|
|
||||||
SerialTTY::SerialTTY(Serial serial)
|
SerialTTY::SerialTTY(Serial serial)
|
||||||
: TTY(0600, 0, 0)
|
: TTY({
|
||||||
|
.c_iflag = ICRNL,
|
||||||
|
.c_oflag = OPOST | ONLCR,
|
||||||
|
.c_cflag = CS8,
|
||||||
|
.c_lflag = ECHO | ICANON,
|
||||||
|
.c_cc = {},
|
||||||
|
.c_ospeed = B38400,
|
||||||
|
.c_ispeed = B38400,
|
||||||
|
}, 0600, 0, 0)
|
||||||
, m_name(MUST(BAN::String::formatted("ttyS{}", s_next_tty_number++)))
|
, m_name(MUST(BAN::String::formatted("ttyS{}", s_next_tty_number++)))
|
||||||
, m_serial(serial)
|
, m_serial(serial)
|
||||||
{}
|
{}
|
||||||
|
@ -235,8 +243,6 @@ namespace Kernel
|
||||||
while (!m_input.empty())
|
while (!m_input.empty())
|
||||||
{
|
{
|
||||||
*ptr = m_input.front();
|
*ptr = m_input.front();
|
||||||
if (*ptr == '\r')
|
|
||||||
*ptr = '\n';
|
|
||||||
m_input.pop();
|
m_input.pop();
|
||||||
ptr++;
|
ptr++;
|
||||||
}
|
}
|
||||||
|
|
|
@ -66,18 +66,11 @@ namespace Kernel
|
||||||
return makedev(DeviceNumber::TTY, s_minor++);
|
return makedev(DeviceNumber::TTY, s_minor++);
|
||||||
}
|
}
|
||||||
|
|
||||||
TTY::TTY(mode_t mode, uid_t uid, gid_t gid)
|
TTY::TTY(termios termios, mode_t mode, uid_t uid, gid_t gid)
|
||||||
: CharacterDevice(mode, uid, gid)
|
: CharacterDevice(mode, uid, gid)
|
||||||
|
, m_termios(termios)
|
||||||
, m_rdev(next_tty_rdev())
|
, m_rdev(next_tty_rdev())
|
||||||
{
|
{ }
|
||||||
// FIXME: add correct baud and flags
|
|
||||||
m_termios.c_iflag = 0;
|
|
||||||
m_termios.c_oflag = 0;
|
|
||||||
m_termios.c_cflag = CS8;
|
|
||||||
m_termios.c_lflag = ECHO | ICANON;
|
|
||||||
m_termios.c_ospeed = B38400;
|
|
||||||
m_termios.c_ispeed = B38400;
|
|
||||||
}
|
|
||||||
|
|
||||||
BAN::RefPtr<TTY> TTY::current()
|
BAN::RefPtr<TTY> TTY::current()
|
||||||
{
|
{
|
||||||
|
@ -228,6 +221,17 @@ namespace Kernel
|
||||||
|
|
||||||
LockGuard _(m_mutex);
|
LockGuard _(m_mutex);
|
||||||
|
|
||||||
|
if ((m_termios.c_iflag & ISTRIP))
|
||||||
|
ch &= 0x7F;
|
||||||
|
if ((m_termios.c_iflag & IGNCR) && ch == '\r')
|
||||||
|
return;
|
||||||
|
uint8_t conv = ch;
|
||||||
|
if ((m_termios.c_iflag & ICRNL) && ch == '\r')
|
||||||
|
conv = '\n';
|
||||||
|
if ((m_termios.c_iflag & INLCR) && ch == '\n')
|
||||||
|
conv = '\r';
|
||||||
|
ch = conv;
|
||||||
|
|
||||||
// ^C
|
// ^C
|
||||||
if (ch == '\x03')
|
if (ch == '\x03')
|
||||||
{
|
{
|
||||||
|
@ -252,6 +256,10 @@ namespace Kernel
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FIXME: don't ignore these bytes
|
||||||
|
if (m_output.bytes >= m_output.buffer.size())
|
||||||
|
return;
|
||||||
|
|
||||||
m_output.buffer[m_output.bytes++] = ch;
|
m_output.buffer[m_output.bytes++] = ch;
|
||||||
|
|
||||||
if (m_termios.c_lflag & ECHO)
|
if (m_termios.c_lflag & ECHO)
|
||||||
|
@ -280,7 +288,7 @@ namespace Kernel
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ch == '\n' || !(m_termios.c_lflag & ICANON))
|
if (ch == '\n' || !(m_termios.c_lflag & ICANON) || m_output.bytes == m_output.buffer.size())
|
||||||
{
|
{
|
||||||
m_output.flush = true;
|
m_output.flush = true;
|
||||||
epoll_notify(EPOLLIN);
|
epoll_notify(EPOLLIN);
|
||||||
|
@ -334,9 +342,16 @@ namespace Kernel
|
||||||
bool TTY::putchar(uint8_t ch)
|
bool TTY::putchar(uint8_t ch)
|
||||||
{
|
{
|
||||||
SpinLockGuard _(m_write_lock);
|
SpinLockGuard _(m_write_lock);
|
||||||
if (m_tty_ctrl.draw_graphics)
|
if (!m_tty_ctrl.draw_graphics)
|
||||||
return putchar_impl(ch);
|
|
||||||
return true;
|
return true;
|
||||||
|
if (m_termios.c_oflag & OPOST)
|
||||||
|
{
|
||||||
|
if ((m_termios.c_oflag & ONLCR) && ch == '\n')
|
||||||
|
return putchar_impl('\r') && putchar_impl('\n');
|
||||||
|
if ((m_termios.c_oflag & OCRNL) && ch == '\r')
|
||||||
|
return putchar_impl('\n');
|
||||||
|
}
|
||||||
|
return putchar_impl(ch);
|
||||||
}
|
}
|
||||||
|
|
||||||
BAN::ErrorOr<size_t> TTY::read_impl(off_t, BAN::ByteSpan buffer)
|
BAN::ErrorOr<size_t> TTY::read_impl(off_t, BAN::ByteSpan buffer)
|
||||||
|
@ -353,7 +368,13 @@ namespace Kernel
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t to_copy = BAN::Math::min<size_t>(buffer.size(), m_output.bytes);
|
const size_t max_to_copy = BAN::Math::min<size_t>(buffer.size(), m_output.bytes);
|
||||||
|
size_t to_copy = max_to_copy;
|
||||||
|
if (m_termios.c_lflag & ICANON)
|
||||||
|
for (to_copy = 1; to_copy < max_to_copy; to_copy++)
|
||||||
|
if (m_output.buffer[to_copy - 1] == '\n')
|
||||||
|
break;
|
||||||
|
|
||||||
memcpy(buffer.data(), m_output.buffer.data(), to_copy);
|
memcpy(buffer.data(), m_output.buffer.data(), to_copy);
|
||||||
|
|
||||||
memmove(m_output.buffer.data(), m_output.buffer.data() + to_copy, m_output.bytes - to_copy);
|
memmove(m_output.buffer.data(), m_output.buffer.data() + to_copy, m_output.bytes - to_copy);
|
||||||
|
|
|
@ -36,7 +36,15 @@ namespace Kernel
|
||||||
}
|
}
|
||||||
|
|
||||||
VirtualTTY::VirtualTTY(BAN::RefPtr<TerminalDriver> driver)
|
VirtualTTY::VirtualTTY(BAN::RefPtr<TerminalDriver> driver)
|
||||||
: TTY(0600, 0, 0)
|
: TTY({
|
||||||
|
.c_iflag = 0,
|
||||||
|
.c_oflag = 0,
|
||||||
|
.c_cflag = CS8,
|
||||||
|
.c_lflag = ECHO | ICANON,
|
||||||
|
.c_cc = {},
|
||||||
|
.c_ospeed = B38400,
|
||||||
|
.c_ispeed = B38400,
|
||||||
|
}, 0600, 0, 0)
|
||||||
, m_name(MUST(BAN::String::formatted("tty{}", s_next_tty_number++)))
|
, m_name(MUST(BAN::String::formatted("tty{}", s_next_tty_number++)))
|
||||||
, m_terminal_driver(driver)
|
, m_terminal_driver(driver)
|
||||||
, m_palette(driver->palette())
|
, m_palette(driver->palette())
|
||||||
|
|
Loading…
Reference in New Issue