1
1
mirror of https://github.com/wez/wezterm.git synced 2024-11-22 13:16:39 +03:00

kill and reap ProxyCommand

The wrapper struct ensures ensures the child process spawned for
the ProxyCommand is cleaned up under all the various error scenarios
(such as auth failures etc), as well as in the normal successful use
case. This includes killing it if necessary, and then waiting for it.
This commit is contained in:
Naitik Shah 2024-05-31 11:21:49 +04:00 committed by Wez Furlong
parent 57be095264
commit 463df9ebed

View File

@ -205,7 +205,7 @@ impl SessionInner {
sess.set_option(libssh_rs::SshOption::HostKeys(host_key.to_string()))?;
}
let sock =
let (sock, _child) =
self.connect_to_host(&hostname, port, verbose, self.config.get("proxycommand"))?;
let raw = {
#[cfg(unix)]
@ -288,7 +288,7 @@ impl SessionInner {
))))
.context("notifying user of banner")?;
let sock =
let (sock, _child) =
self.connect_to_host(&hostname, port, verbose, self.config.get("proxycommand"))?;
let mut sess = ssh2::Session::new()?;
@ -332,7 +332,7 @@ impl SessionInner {
port: u16,
verbose: bool,
proxy_command: Option<&String>,
) -> anyhow::Result<Socket> {
) -> anyhow::Result<(Socket, Option<KillOnDropChild>)> {
match proxy_command.map(|s| s.as_str()) {
Some("none") | None => {}
Some(proxy_command) => {
@ -351,19 +351,25 @@ impl SessionInner {
cmd.stdin(b.as_stdio()?);
cmd.stdout(b.as_stdio()?);
cmd.stderr(std::process::Stdio::inherit());
let _child = cmd
let child = cmd
.spawn()
.with_context(|| format!("spawning ProxyCommand {}", proxy_command))?;
#[cfg(unix)]
unsafe {
use std::os::unix::io::{FromRawFd, IntoRawFd};
return Ok(Socket::from_raw_fd(a.into_raw_fd()));
return Ok((
Socket::from_raw_fd(a.into_raw_fd()),
Some(KillOnDropChild(child)),
));
}
#[cfg(windows)]
unsafe {
use std::os::windows::io::{FromRawSocket, IntoRawSocket};
return Ok(Socket::from_raw_socket(a.into_raw_socket()));
return Ok((
Socket::from_raw_socket(a.into_raw_socket()),
Some(KillOnDropChild(child)),
));
}
}
}
@ -392,7 +398,7 @@ impl SessionInner {
sock.connect(&addr.into())
.with_context(|| format!("Connecting to {hostname}:{port} ({addr:?})"))?;
Ok(sock)
Ok((sock, None))
}
/// Used to restrict to_socket_addrs results to the address
@ -1086,3 +1092,17 @@ where
}
Ok(true)
}
/// A little helper to ensure the Child process is killed on Drop.
struct KillOnDropChild(std::process::Child);
impl Drop for KillOnDropChild {
fn drop(&mut self) {
if let Err(err) = self.0.kill() {
log::error!("Error killing ProxyCommand: {}", err);
}
if let Err(err) = self.0.wait() {
log::error!("Error waiting for ProxyCommand to finish: {}", err);
}
}
}