1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-24 15:17:45 +00:00

Kernel: Implement support for PTY flags ICRNL, OPOST and ONLCR

These are used by OpenSSH. Without those flags new-lines are
all jumbled in the output.
This commit is contained in:
Gunnar Beutner 2021-04-30 04:45:27 +02:00 committed by Andreas Kling
parent f48f26f52d
commit 71f90695c2

View file

@ -68,8 +68,14 @@ KResultOr<size_t> TTY::read(FileDescription&, u64, UserOrKernelBuffer& buffer, s
}); });
} else { } else {
nwritten = buffer.write_buffered<512>(size, [&](u8* data, size_t data_size) { nwritten = buffer.write_buffered<512>(size, [&](u8* data, size_t data_size) {
for (size_t i = 0; i < data_size; i++) for (size_t i = 0; i < data_size; i++) {
data[i] = m_input_buffer.dequeue(); auto ch = m_input_buffer.dequeue();
if (ch == '\r' && m_termios.c_iflag & ICRNL)
ch = '\n';
else if (ch == '\n' && m_termios.c_iflag & INLCR)
ch = '\r';
data[i] = ch;
}
return (ssize_t)data_size; return (ssize_t)data_size;
}); });
} }
@ -87,8 +93,23 @@ KResultOr<size_t> TTY::write(FileDescription&, u64, const UserOrKernelBuffer& bu
return EINTR; return EINTR;
} }
on_tty_write(buffer, size); const size_t num_chars = 256;
return size; ssize_t nread = buffer.read_buffered<num_chars>((size_t)size, [&](const u8* data, size_t buffer_bytes) {
u8 modified_data[num_chars * 2];
size_t extra_chars = 0;
for (size_t i = 0; i < buffer_bytes; ++i) {
auto ch = data[i];
if (ch == '\n' && (m_termios.c_oflag & (OPOST | ONLCR))) {
modified_data[i + extra_chars] = '\r';
extra_chars++;
}
modified_data[i + extra_chars] = ch;
}
on_tty_write(UserOrKernelBuffer::for_kernel_buffer(modified_data), buffer_bytes + extra_chars);
return (ssize_t)buffer_bytes;
});
return nread;
} }
bool TTY::can_read(const FileDescription&, size_t) const bool TTY::can_read(const FileDescription&, size_t) const
@ -284,7 +305,7 @@ void TTY::set_termios(const termios& t)
{ {
m_termios = t; m_termios = t;
dbgln_if(TTY_DEBUG, "{} set_termios: ECHO={}, ISIG={}, ICANON={}, ECHOE={}, ECHOK={}, ECHONL={}, ISTRIP={}, ICRNL={}, INLCR={}, IGNCR={}", dbgln_if(TTY_DEBUG, "{} set_termios: ECHO={}, ISIG={}, ICANON={}, ECHOE={}, ECHOK={}, ECHONL={}, ISTRIP={}, ICRNL={}, INLCR={}, IGNCR={}, OPOST={}, ONLCR={}",
tty_name(), tty_name(),
should_echo_input(), should_echo_input(),
should_generate_signals(), should_generate_signals(),
@ -295,7 +316,9 @@ void TTY::set_termios(const termios& t)
((m_termios.c_iflag & ISTRIP) != 0), ((m_termios.c_iflag & ISTRIP) != 0),
((m_termios.c_iflag & ICRNL) != 0), ((m_termios.c_iflag & ICRNL) != 0),
((m_termios.c_iflag & INLCR) != 0), ((m_termios.c_iflag & INLCR) != 0),
((m_termios.c_iflag & IGNCR) != 0)); ((m_termios.c_iflag & IGNCR) != 0),
((m_termios.c_oflag & OPOST) != 0),
((m_termios.c_oflag & ONLCR) != 0));
} }
int TTY::ioctl(FileDescription&, unsigned request, FlatPtr arg) int TTY::ioctl(FileDescription&, unsigned request, FlatPtr arg)