1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 21:17:44 +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; 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) if (m_closed)
return -EIO; return EIO;
return m_buffer.write(data, size); return m_buffer.write(data, size);
} }

View file

@ -21,7 +21,7 @@ public:
unsigned index() const { return m_index; } unsigned index() const { return m_index; }
String pts_name() const; 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; bool can_write_from_slave() const;
void notify_slave_closed(Badge<SlavePTY>); void notify_slave_closed(Badge<SlavePTY>);
bool is_closed() const { return m_closed; } bool is_closed() const { return m_closed; }

View file

@ -40,11 +40,11 @@ void SlavePTY::echo(u8 ch)
{ {
if (should_echo_input()) { if (should_echo_input()) {
auto buffer = UserOrKernelBuffer::for_kernel_buffer(&ch); 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) { auto result = buffer.read_buffered<128>(size, [&](u8 const* data, size_t data_size) {
for (size_t i = 0; i < data_size; ++i) 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(); 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(); m_time_of_last_write = kgettimeofday().to_truncated_seconds();
return m_master->on_slave_write(data, size); return m_master->on_slave_write(data, size);

View file

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

View file

@ -88,7 +88,7 @@ KResultOr<size_t> TTY::write(FileDescription&, u64, const UserOrKernelBuffer& bu
} }
constexpr size_t num_chars = 256; 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]; u8 modified_data[num_chars * 2];
size_t modified_data_size = 0; size_t modified_data_size = 0;
for (size_t i = 0; i < buffer_bytes; ++i) { 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; modified_data[modified_data_size++] = out_ch;
}); });
} }
ssize_t bytes_written = on_tty_write(UserOrKernelBuffer::for_kernel_buffer(modified_data), modified_data_size); auto bytes_written_or_error = on_tty_write(UserOrKernelBuffer::for_kernel_buffer(modified_data), modified_data_size);
VERIFY(bytes_written != 0); VERIFY(bytes_written_or_error.is_error() || bytes_written_or_error.value() != 0);
if (bytes_written < 0 || !(m_termios.c_oflag & OPOST) || !(m_termios.c_oflag & ONLCR)) if (bytes_written_or_error.is_error() || !(m_termios.c_oflag & OPOST) || !(m_termios.c_oflag & ONLCR))
return bytes_written; return bytes_written_or_error;
if ((size_t)bytes_written == modified_data_size) auto bytes_written = bytes_written_or_error.value();
return (ssize_t)buffer_bytes; if (bytes_written == modified_data_size)
return buffer_bytes;
// Degenerate case where we converted some newlines and encountered a partial write // Degenerate case where we converted some newlines and encountered a partial write
// Calculate where in the input buffer the last character would have been // Calculate where in the input buffer the last character would have been
size_t pos_data = 0; 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') if (data[pos_data] == '\n')
pos_modified_data += 2; pos_modified_data += 2;
else else
@ -118,7 +119,7 @@ KResultOr<size_t> TTY::write(FileDescription&, u64, const UserOrKernelBuffer& bu
if (pos_modified_data > bytes_written) if (pos_modified_data > bytes_written)
--pos_data; --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; } virtual mode_t required_mode() const override { return 0620; }
protected: 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); void set_size(unsigned short columns, unsigned short rows);
TTY(unsigned major, unsigned minor); 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 global_lock(ConsoleManagement::the().tty_write_lock());
ScopedSpinLock lock(m_lock); ScopedSpinLock lock(m_lock);
@ -276,9 +276,7 @@ ssize_t VirtualConsole::on_tty_write(const UserOrKernelBuffer& data, ssize_t siz
}); });
if (m_active) if (m_active)
flush_dirty_lines(); flush_dirty_lines();
if (result.is_error()) return result;
return result.error();
return (ssize_t)result.value();
} }
void VirtualConsole::set_active(bool active) void VirtualConsole::set_active(bool active)

View file

@ -91,7 +91,7 @@ private:
virtual void on_key_pressed(KeyEvent) override; virtual void on_key_pressed(KeyEvent) override;
// ^TTY // ^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 String const& tty_name() const override { return m_tty_name; }
virtual void echo(u8) override; virtual void echo(u8) override;

View file

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