1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 21:57:43 +00:00

Kernel: Use KResultOr<size_t> throughout the TTY subsystem

Previously the VirtualConsole::on_tty_write() method would return an
incorrect value when an error had occurred. This prompted me to
update the TTY subsystem to use KResultOr<size_t> everywhere.
This commit is contained in:
Gunnar Beutner 2021-06-16 15:20:35 +02:00 committed by Andreas Kling
parent a49a15cabf
commit 1c3346e3ce
9 changed files with 29 additions and 29 deletions

View file

@ -78,10 +78,10 @@ void MasterPTY::notify_slave_closed(Badge<SlavePTY>)
m_slave = nullptr;
}
ssize_t MasterPTY::on_slave_write(const UserOrKernelBuffer& data, ssize_t size)
KResultOr<size_t> MasterPTY::on_slave_write(const UserOrKernelBuffer& data, size_t size)
{
if (m_closed)
return -EIO;
return EIO;
return m_buffer.write(data, size);
}

View file

@ -21,7 +21,7 @@ public:
unsigned index() const { return m_index; }
String pts_name() const;
ssize_t on_slave_write(const UserOrKernelBuffer&, ssize_t);
KResultOr<size_t> on_slave_write(const UserOrKernelBuffer&, size_t);
bool can_write_from_slave() const;
void notify_slave_closed(Badge<SlavePTY>);
bool is_closed() const { return m_closed; }

View file

@ -40,11 +40,11 @@ void SlavePTY::echo(u8 ch)
{
if (should_echo_input()) {
auto buffer = UserOrKernelBuffer::for_kernel_buffer(&ch);
m_master->on_slave_write(buffer, 1);
[[maybe_unused]] auto result = m_master->on_slave_write(buffer, 1);
}
}
void SlavePTY::on_master_write(const UserOrKernelBuffer& buffer, ssize_t size)
void SlavePTY::on_master_write(const UserOrKernelBuffer& buffer, size_t size)
{
auto result = buffer.read_buffered<128>(size, [&](u8 const* data, size_t data_size) {
for (size_t i = 0; i < data_size; ++i)
@ -55,7 +55,7 @@ void SlavePTY::on_master_write(const UserOrKernelBuffer& buffer, ssize_t size)
evaluate_block_conditions();
}
ssize_t SlavePTY::on_tty_write(const UserOrKernelBuffer& data, ssize_t size)
KResultOr<size_t> SlavePTY::on_tty_write(const UserOrKernelBuffer& data, size_t size)
{
m_time_of_last_write = kgettimeofday().to_truncated_seconds();
return m_master->on_slave_write(data, size);

View file

@ -17,7 +17,7 @@ class SlavePTY final : public TTY {
public:
virtual ~SlavePTY() override;
void on_master_write(const UserOrKernelBuffer&, ssize_t);
void on_master_write(const UserOrKernelBuffer&, size_t);
unsigned index() const { return m_index; }
time_t time_of_last_write() const { return m_time_of_last_write; }
@ -27,7 +27,7 @@ public:
private:
// ^TTY
virtual String const& tty_name() const override;
virtual ssize_t on_tty_write(const UserOrKernelBuffer&, ssize_t) override;
virtual KResultOr<size_t> on_tty_write(const UserOrKernelBuffer&, size_t) override;
virtual void echo(u8) override;
// ^CharacterDevice

View file

@ -88,7 +88,7 @@ KResultOr<size_t> TTY::write(FileDescription&, u64, const UserOrKernelBuffer& bu
}
constexpr size_t num_chars = 256;
return buffer.read_buffered<num_chars>(size, [&](u8 const* data, size_t buffer_bytes) {
return buffer.read_buffered<num_chars>(size, [&](u8 const* data, size_t buffer_bytes) -> KResultOr<size_t> {
u8 modified_data[num_chars * 2];
size_t modified_data_size = 0;
for (size_t i = 0; i < buffer_bytes; ++i) {
@ -96,18 +96,19 @@ KResultOr<size_t> TTY::write(FileDescription&, u64, const UserOrKernelBuffer& bu
modified_data[modified_data_size++] = out_ch;
});
}
ssize_t bytes_written = on_tty_write(UserOrKernelBuffer::for_kernel_buffer(modified_data), modified_data_size);
VERIFY(bytes_written != 0);
if (bytes_written < 0 || !(m_termios.c_oflag & OPOST) || !(m_termios.c_oflag & ONLCR))
return bytes_written;
if ((size_t)bytes_written == modified_data_size)
return (ssize_t)buffer_bytes;
auto bytes_written_or_error = on_tty_write(UserOrKernelBuffer::for_kernel_buffer(modified_data), modified_data_size);
VERIFY(bytes_written_or_error.is_error() || bytes_written_or_error.value() != 0);
if (bytes_written_or_error.is_error() || !(m_termios.c_oflag & OPOST) || !(m_termios.c_oflag & ONLCR))
return bytes_written_or_error;
auto bytes_written = bytes_written_or_error.value();
if (bytes_written == modified_data_size)
return buffer_bytes;
// Degenerate case where we converted some newlines and encountered a partial write
// Calculate where in the input buffer the last character would have been
size_t pos_data = 0;
for (ssize_t pos_modified_data = 0; pos_modified_data < bytes_written; ++pos_data) {
for (size_t pos_modified_data = 0; pos_modified_data < bytes_written; ++pos_data) {
if (data[pos_data] == '\n')
pos_modified_data += 2;
else
@ -118,7 +119,7 @@ KResultOr<size_t> TTY::write(FileDescription&, u64, const UserOrKernelBuffer& bu
if (pos_modified_data > bytes_written)
--pos_data;
}
return (ssize_t)pos_data;
return pos_data;
});
}

View file

@ -53,7 +53,7 @@ public:
virtual mode_t required_mode() const override { return 0620; }
protected:
virtual ssize_t on_tty_write(const UserOrKernelBuffer&, ssize_t) = 0;
virtual KResultOr<size_t> on_tty_write(const UserOrKernelBuffer&, size_t) = 0;
void set_size(unsigned short columns, unsigned short rows);
TTY(unsigned major, unsigned minor);

View file

@ -265,7 +265,7 @@ void VirtualConsole::on_key_pressed(KeyEvent event)
});
}
ssize_t VirtualConsole::on_tty_write(const UserOrKernelBuffer& data, ssize_t size)
KResultOr<size_t> VirtualConsole::on_tty_write(const UserOrKernelBuffer& data, size_t size)
{
ScopedSpinLock global_lock(ConsoleManagement::the().tty_write_lock());
ScopedSpinLock lock(m_lock);
@ -276,9 +276,7 @@ ssize_t VirtualConsole::on_tty_write(const UserOrKernelBuffer& data, ssize_t siz
});
if (m_active)
flush_dirty_lines();
if (result.is_error())
return result.error();
return (ssize_t)result.value();
return result;
}
void VirtualConsole::set_active(bool active)

View file

@ -91,7 +91,7 @@ private:
virtual void on_key_pressed(KeyEvent) override;
// ^TTY
virtual ssize_t on_tty_write(const UserOrKernelBuffer&, ssize_t) override;
virtual KResultOr<size_t> on_tty_write(const UserOrKernelBuffer&, size_t) override;
virtual String const& tty_name() const override { return m_tty_name; }
virtual void echo(u8) override;

View file

@ -133,12 +133,13 @@ public:
auto to_copy = min(sizeof(buffer), len - nread);
if (!read(buffer, nread, to_copy))
return EFAULT;
ssize_t copied = f(buffer, to_copy);
if (copied < 0)
return copied;
VERIFY((size_t)copied <= to_copy);
nread += (size_t)copied;
if ((size_t)copied < to_copy)
KResultOr<size_t> copied_or_error = f(buffer, to_copy);
if (copied_or_error.is_error())
return copied_or_error.error();
auto copied = copied_or_error.value();
VERIFY(copied <= to_copy);
nread += copied;
if (copied < to_copy)
break;
}
return nread;