LibC/Kernel: Cleanup termios code

This is still not correct, but much better than it used to be
This commit is contained in:
2024-07-30 11:10:43 +03:00
parent 9bc02c81f8
commit 681d8327f5
9 changed files with 99 additions and 49 deletions

View File

@@ -332,39 +332,38 @@ namespace Kernel
ASSERT_NOT_REACHED();
}
BAN::ErrorOr<long> Process::sys_gettermios(::termios* termios)
BAN::ErrorOr<long> Process::sys_tcgetattr(int fildes, termios* termios)
{
LockGuard _(m_process_lock);
TRY(validate_pointer_access(termios, sizeof(::termios)));
TRY(validate_pointer_access(termios, sizeof(termios)));
if (!m_controlling_terminal)
auto inode = TRY(m_open_file_descriptors.inode_of(fildes));
if (!inode->is_tty())
return BAN::Error::from_errno(ENOTTY);
Kernel::termios ktermios = m_controlling_terminal->get_termios();
termios->c_lflag = 0;
if (ktermios.canonical)
termios->c_lflag |= ICANON;
if (ktermios.echo)
termios->c_lflag |= ECHO;
static_cast<TTY*>(inode.ptr())->get_termios(termios);
return 0;
}
BAN::ErrorOr<long> Process::sys_settermios(const ::termios* termios)
BAN::ErrorOr<long> Process::sys_tcsetattr(int fildes, int optional_actions, const termios* termios)
{
if (optional_actions != TCSANOW)
return BAN::Error::from_errno(EINVAL);
LockGuard _(m_process_lock);
TRY(validate_pointer_access(termios, sizeof(::termios)));
TRY(validate_pointer_access(termios, sizeof(termios)));
if (!m_controlling_terminal)
auto inode = TRY(m_open_file_descriptors.inode_of(fildes));
if (!inode->is_tty())
return BAN::Error::from_errno(ENOTTY);
Kernel::termios ktermios;
ktermios.echo = termios->c_lflag & ECHO;
ktermios.canonical = termios->c_lflag & ICANON;
TRY(static_cast<TTY*>(inode.ptr())->set_termios(termios));
// FIXME: SIGTTOU
m_controlling_terminal->set_termios(ktermios);
return 0;
}

View File

@@ -234,7 +234,7 @@ namespace Kernel
}
// ^D + canonical
if (ch == '\x04' && m_termios.canonical)
if (ch == '\x04' && (m_termios.c_lflag & ICANON))
{
m_output.flush = true;
m_output.thread_blocker.unblock();
@@ -242,7 +242,7 @@ namespace Kernel
}
// backspace + canonical
if (ch == '\b' && m_termios.canonical)
if (ch == '\b' && (m_termios.c_lflag & ICANON))
{
do_backspace();
return;
@@ -250,7 +250,7 @@ namespace Kernel
m_output.buffer[m_output.bytes++] = ch;
if (m_termios.echo)
if (m_termios.c_lflag & ECHO)
{
if ((ch <= 31 || ch == 127) && ch != '\n')
{
@@ -276,7 +276,7 @@ namespace Kernel
}
}
if (ch == '\n' || !m_termios.canonical)
if (ch == '\n' || !(m_termios.c_lflag & ICANON))
{
m_output.flush = true;
m_output.thread_blocker.unblock();