diff options
| author | JJ Liebig <jonathan.liebig@gmail.com> | 2026-09-08 23:08:42 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-09-09 00:08:42 +0300 |
| commit | 8996fc54fe4596368a1677821b1a390a70c56ab0 (patch) | |
| tree | 65ff0293a3ee17b4acc50539bff382388abaf927 /src/platform/windows.rs | |
| parent | 68c7b78ec237034cbb0e21c8666842ed7991641d (diff) | |
fix: support preinstalled windows remote hosts (#3661)
* fix: support windows hosts in saved ssh machines
refs #3651
* fix: keep windows ssh bridge writes blocking
refs #3651
* fix: close saved windows ssh bootstrap input
refs #3651
* refactor: simplify remote bridge helpers
refs #3651
* refactor: isolate remote bridge platform behavior
refs #3651
* fix: close captured ssh input under windows consoles
refs #3651
* test: remove redundant remote command assertions
refs #3651
refs #3701
* test: handle framed ssh commands in machine setup
refs #3651
---------
Co-authored-by: Ogulcan Celik <ogulcancelik@gmail.com>
Diffstat (limited to 'src/platform/windows.rs')
| -rw-r--r-- | src/platform/windows.rs | 81 |
1 files changed, 50 insertions, 31 deletions
diff --git a/src/platform/windows.rs b/src/platform/windows.rs index e58bacae..87945daf 100644 --- a/src/platform/windows.rs +++ b/src/platform/windows.rs @@ -52,6 +52,54 @@ pub(crate) fn wait_client_stream_readable( Ok(()) } +pub(crate) fn forward_remote_bridge_stdio(stream: crate::ipc::LocalStream) -> std::io::Result<()> { + use interprocess::TryClone as _; + use std::sync::atomic::{AtomicBool, Ordering}; + + let mut stdout = std::io::stdout().lock(); + let mut socket_to_stdout = stream.try_clone()?; + let mut stdin_to_socket = stream; + let upload_done = Arc::new(AtomicBool::new(false)); + let upload_done_worker = Arc::clone(&upload_done); + let _upload = std::thread::spawn(move || { + let mut stdin = std::io::stdin(); + let _ = copy_flush(&mut stdin, &mut stdin_to_socket); + upload_done_worker.store(true, Ordering::Release); + }); + + let mut buffer = [0_u8; 16 * 1024]; + while !upload_done.load(Ordering::Acquire) { + match crate::ipc::poll_local_stream_read_count(&mut socket_to_stdout, &mut buffer)? { + crate::ipc::LocalStreamReadCount::Data(read) => { + std::io::Write::write_all(&mut stdout, &buffer[..read])?; + std::io::Write::flush(&mut stdout)?; + } + crate::ipc::LocalStreamReadCount::Pending => { + std::thread::sleep(Duration::from_millis(1)); + } + crate::ipc::LocalStreamReadCount::Closed => break, + } + } + Ok(()) +} + +fn copy_flush<R: std::io::Read, W: std::io::Write>( + reader: &mut R, + writer: &mut W, +) -> std::io::Result<()> { + let mut buffer = [0_u8; 16 * 1024]; + loop { + let read = match reader.read(&mut buffer) { + Ok(0) => return Ok(()), + Ok(read) => read, + Err(err) if err.kind() == std::io::ErrorKind::Interrupted => continue, + Err(err) => return Err(err), + }; + writer.write_all(&buffer[..read])?; + writer.flush()?; + } +} + pub(super) fn read_terminal_grid_size() -> std::io::Result<(u16, u16)> { crossterm::terminal::size() } @@ -669,7 +717,7 @@ fn powershell_agent_script(argv: &[String]) -> Option<String> { .join(" "); let command_line = args .iter() - .map(|arg| quote_windows_command_line_arg(arg)) + .map(|arg| super::quote_windows_command_line_arg(arg)) .collect::<Vec<_>>() .join(" "); Some(format!( @@ -682,35 +730,6 @@ fn powershell_agent_script(argv: &[String]) -> Option<String> { )) } -fn quote_windows_command_line_arg(value: &str) -> String { - if !value.is_empty() - && !value - .chars() - .any(|ch| matches!(ch, ' ' | '\t' | '\n' | '\x0b' | '"')) - { - return value.to_string(); - } - - let mut quoted = String::from("\""); - let mut backslashes = 0; - for ch in value.chars() { - if ch == '\\' { - backslashes += 1; - continue; - } - if ch == '"' { - quoted.push_str(&"\\".repeat(backslashes * 2 + 1)); - } else { - quoted.push_str(&"\\".repeat(backslashes)); - } - backslashes = 0; - quoted.push(ch); - } - quoted.push_str(&"\\".repeat(backslashes * 2)); - quoted.push('"'); - quoted -} - fn cmd_encoded_powershell_command(script: &str) -> String { use base64::Engine as _; @@ -1015,7 +1034,7 @@ fn windows_command_line(command: &std::process::Command) -> std::io::Result<Stri .chain(command.get_args()) .map(|value| { unicode_windows_value(value, "server command argument") - .map(|value| quote_windows_command_line_arg(&value)) + .map(|value| super::quote_windows_command_line_arg(&value)) }) .collect::<std::io::Result<Vec<_>>>() .map(|parts| parts.join(" ")) |
