mirror of
https://github.com/SerenityOS/serenity.git
synced 2026-11-07 04:29:30 -10:00
SSHServer: Add support for the window-change request
With this patch, SSHServer is able to update the pty on the server when the size of the client's window is updated. Resizing your terminal emulator's window while being connected to SSHServer no longer make you disconnect. While the implementation is functional, it seems to have quite more latency than with a regular SSH server, so visual artifacts may appear when aggressively resizing the window.
This commit is contained in:
1 parent
76175e09ba
commit
ceed7af2e2
2 files changed
+38
No files matched your search
@@ -636,6 +636,11 @@ ErrorOr<void> SSHClient::handle_channel_request(GenericMessage& message)
|
||||
return {};
|
||||
}
|
||||
|
||||
if (request_type == "window-change"sv.bytes()) {
|
||||
TRY(handle_channel_window_change(session, message));
|
||||
return {};
|
||||
}
|
||||
|
||||
return Error::from_string_literal("Unsupported channel request");
|
||||
}
|
||||
|
||||
@@ -887,6 +892,38 @@ ErrorOr<void> SSHClient::handle_channel_pseudo_terminal(Session& session, Generi
|
||||
return TRY(send_channel_success_message(session));
|
||||
}
|
||||
|
||||
// 6.7. Window Dimension Change Message
|
||||
// https://datatracker.ietf.org/doc/html/rfc4254#section-6.7
|
||||
ErrorOr<void> SSHClient::handle_channel_window_change(Session& session, GenericMessage& message)
|
||||
{
|
||||
u32 width_characters = TRY(message.payload.read_value<NetworkOrdered<u32>>());
|
||||
u32 height_rows = TRY(message.payload.read_value<NetworkOrdered<u32>>());
|
||||
u32 width_pixels = TRY(message.payload.read_value<NetworkOrdered<u32>>());
|
||||
u32 height_pixels = TRY(message.payload.read_value<NetworkOrdered<u32>>());
|
||||
|
||||
dbgln_if(SSH_DEBUG, "PTY window change: w={}, h={}, w_px={}, h_px={}",
|
||||
width_characters, height_rows, width_pixels, height_pixels);
|
||||
|
||||
if (!session.system.has<Shell>())
|
||||
return Error::from_string_literal("Requested a window change while no shell is present");
|
||||
|
||||
winsize ws {
|
||||
.ws_row = static_cast<u16>(height_rows),
|
||||
.ws_col = static_cast<u16>(width_characters),
|
||||
.ws_xpixel = static_cast<u16>(width_pixels),
|
||||
.ws_ypixel = static_cast<u16>(height_pixels),
|
||||
};
|
||||
|
||||
auto maybe_error = Core::System::tcsetwinsize(session.system.get<Shell>().stdin_->fd(), ws);
|
||||
|
||||
if (maybe_error.is_error()) {
|
||||
dbgln("Unable to set pty dimensions: {}", maybe_error.error());
|
||||
}
|
||||
|
||||
// "A response SHOULD NOT be sent to this message."
|
||||
return {};
|
||||
}
|
||||
|
||||
ErrorOr<void> SSHClient::send_channel_success_message(Session const& session)
|
||||
{
|
||||
AllocatingMemoryStream stream;
|
||||
|
||||
@@ -85,6 +85,7 @@ private:
|
||||
ErrorOr<void> handle_channel_data(GenericMessage&);
|
||||
ErrorOr<void> handle_channel_subsystem(Session&, GenericMessage&);
|
||||
ErrorOr<void> handle_channel_pseudo_terminal(Session&, GenericMessage&);
|
||||
ErrorOr<void> handle_channel_window_change(Session&, GenericMessage&);
|
||||
ErrorOr<void> handle_channel_exec(NonnullRefPtr<Session> const&, GenericMessage&);
|
||||
ErrorOr<void> handle_channel_shell(NonnullRefPtr<Session> const&);
|
||||
ErrorOr<void> send_channel_success_message(Session const&);
|
||||
|
||||
Reference in new issue
Block a user