diff --git a/src/shared/inc/lxinitshared.h b/src/shared/inc/lxinitshared.h index ca7d204..f0499d0 100644 --- a/src/shared/inc/lxinitshared.h +++ b/src/shared/inc/lxinitshared.h @@ -1666,10 +1666,8 @@ struct WSLA_TTY_RELAY int32_t TtyInput; int32_t TtyOutput; int32_t TtyControl; - uint32_t Rows; - uint32_t Columns; - PRETTY_PRINT(FIELD(Header), FIELD(TtyMaster), FIELD(TtyInput), FIELD(TtyOutput), FIELD(TtyControl), FIELD(Rows), FIELD(Columns)); + PRETTY_PRINT(FIELD(Header), FIELD(TtyMaster), FIELD(TtyInput), FIELD(TtyOutput), FIELD(TtyControl)); }; struct WSLA_ACCEPT diff --git a/src/windows/common/WSLAProcessLauncher.cpp b/src/windows/common/WSLAProcessLauncher.cpp index 6e2b4cd..3a2e47a 100644 --- a/src/windows/common/WSLAProcessLauncher.cpp +++ b/src/windows/common/WSLAProcessLauncher.cpp @@ -48,6 +48,12 @@ void WSLAProcessLauncher::AddFd(WSLA_PROCESS_FD Fd) m_fds.push_back(Fd); } +void WSLAProcessLauncher::SetTtySize(ULONG Rows, ULONG Columns) +{ + m_rows = Rows; + m_columns = Columns; +} + std::tuple, std::vector> WSLAProcessLauncher::CreateProcessOptions() { std::vector commandLine; @@ -64,6 +70,8 @@ std::tuple, std::vector(m_fds.size()); options.Environment = environment.data(); options.EnvironmentCount = static_cast(environment.size()); + options.TtyColumns = m_columns; + options.TtyRows = m_rows; return std::make_tuple(options, std::move(commandLine), std::move(environment)); } diff --git a/src/windows/common/WSLAProcessLauncher.h b/src/windows/common/WSLAProcessLauncher.h index 2b1069e..1b26ec0 100644 --- a/src/windows/common/WSLAProcessLauncher.h +++ b/src/windows/common/WSLAProcessLauncher.h @@ -96,6 +96,8 @@ protected: std::string m_executable; std::vector m_arguments; std::vector m_environment; + DWORD m_rows = 0; + DWORD m_columns = 0; }; } // namespace wsl::windows::common \ No newline at end of file diff --git a/src/windows/common/WslClient.cpp b/src/windows/common/WslClient.cpp index 087981f..bd3f9e4 100644 --- a/src/windows/common/WslClient.cpp +++ b/src/windows/common/WslClient.cpp @@ -1606,21 +1606,23 @@ int WslaShell(_In_ std::wstring_view commandLine) THROW_HR_IF(E_FAIL, initProcess.WaitAndCaptureOutput().Code != 0); } + // Get the terminal size. + HANDLE Stdout = GetStdHandle(STD_OUTPUT_HANDLE); + HANDLE Stdin = GetStdHandle(STD_INPUT_HANDLE); + + CONSOLE_SCREEN_BUFFER_INFOEX Info{}; + Info.cbSize = sizeof(Info); + THROW_IF_WIN32_BOOL_FALSE(::GetConsoleScreenBufferInfoEx(Stdout, &Info)); + wsl::windows::common::WSLAProcessLauncher launcher{shell, {shell}, {"TERM=xterm-256color"}, ProcessFlags::None}; launcher.AddFd(WSLA_PROCESS_FD{.Fd = 0, .Type = WSLAFdTypeTerminalInput}); launcher.AddFd(WSLA_PROCESS_FD{.Fd = 1, .Type = WSLAFdTypeTerminalOutput}); launcher.AddFd(WSLA_PROCESS_FD{.Fd = 2, .Type = WSLAFdTypeTerminalControl}); - - // Add the terminal size. - CONSOLE_SCREEN_BUFFER_INFOEX Info{}; - Info.cbSize = sizeof(Info); + launcher.SetTtySize(Info.srWindow.Bottom - Info.srWindow.Top + 1, Info.srWindow.Right - Info.srWindow.Left + 1); auto process = launcher.Launch(*session); // Configure console for interactive usage. - - HANDLE Stdout = GetStdHandle(STD_OUTPUT_HANDLE); - HANDLE Stdin = GetStdHandle(STD_INPUT_HANDLE); { DWORD OutputMode{}; THROW_LAST_ERROR_IF(!::GetConsoleMode(Stdout, &OutputMode)); diff --git a/src/windows/wslaservice/exe/WSLAVirtualMachine.cpp b/src/windows/wslaservice/exe/WSLAVirtualMachine.cpp index 3de111c..0c8265c 100644 --- a/src/windows/wslaservice/exe/WSLAVirtualMachine.cpp +++ b/src/windows/wslaservice/exe/WSLAVirtualMachine.cpp @@ -727,7 +727,8 @@ std::tuple WSLAVirtualMachine::For return Fork(m_initChannel, Type); } -std::tuple WSLAVirtualMachine::Fork(wsl::shared::SocketChannel& Channel, enum WSLA_FORK::ForkType Type) +std::tuple WSLAVirtualMachine::Fork( + wsl::shared::SocketChannel& Channel, enum WSLA_FORK::ForkType Type, ULONG TtyRows, ULONG TtyColumns) { uint32_t port{}; int32_t pid{}; @@ -737,8 +738,8 @@ std::tuple WSLAVirtualMachine::For WSLA_FORK message; message.ForkType = Type; - message.TtyColumns = 80; - message.TtyRows = 80; + message.TtyColumns = static_cast(TtyColumns); + message.TtyRows = static_cast(TtyRows); const auto& response = Channel.Transaction(message); port = response.Port; pid = response.Pid; @@ -857,14 +858,12 @@ Microsoft::WRL::ComPtr WSLAVirtualMachine::CreateLinuxProcess(_In_ // If this is an interactive tty, we need a relay process if (interactiveTty) { - auto [grandChildPid, ptyMaster, grandChildChannel] = Fork(childChannel, WSLA_FORK::Pty); + auto [grandChildPid, ptyMaster, grandChildChannel] = Fork(childChannel, WSLA_FORK::Pty, Options.TtyRows, Options.TtyColumns); WSLA_TTY_RELAY relayMessage{}; relayMessage.TtyMaster = ptyMaster; relayMessage.TtyInput = ttyInput->Fd; relayMessage.TtyOutput = ttyOutput->Fd; relayMessage.TtyControl = ttyControl == nullptr ? -1 : ttyControl->Fd; - relayMessage.Rows = Options.TtyRows; - relayMessage.Columns = Options.TtyColumns; childChannel.SendMessage(relayMessage); auto result = ExpectClosedChannelOrError(childChannel); diff --git a/src/windows/wslaservice/exe/WSLAVirtualMachine.h b/src/windows/wslaservice/exe/WSLAVirtualMachine.h index 9019aa7..a2ed053 100644 --- a/src/windows/wslaservice/exe/WSLAVirtualMachine.h +++ b/src/windows/wslaservice/exe/WSLAVirtualMachine.h @@ -82,7 +82,8 @@ private: void OnCrash(_In_ const HCS_EVENT* Event); std::tuple Fork(enum WSLA_FORK::ForkType Type); - std::tuple Fork(wsl::shared::SocketChannel& Channel, enum WSLA_FORK::ForkType Type); + std::tuple Fork( + wsl::shared::SocketChannel& Channel, enum WSLA_FORK::ForkType Type, ULONG TtyRows = 0, ULONG TtyColumns = 0); int32_t ExpectClosedChannelOrError(wsl::shared::SocketChannel& Channel); ConnectedSocket ConnectSocket(wsl::shared::SocketChannel& Channel, int32_t Fd);