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:
parent
a49a15cabf
commit
1c3346e3ce
9 changed files with 29 additions and 29 deletions
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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; }
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue