use std::process::Stdio;
use anyhow::{Context, Result};
use tokio::io::{BufReader, BufWriter};
use tokio::process::{Child, ChildStdin, ChildStdout, Command};
const WRITE_BUF: usize = 256 * 1024;
pub struct SshChild(#[allow(dead_code)] Child);
type Halves = (SshChild, BufWriter<ChildStdin>, BufReader<ChildStdout>);
pub fn open(host: &str) -> Result<Halves> {
let mut child = Command::new("ssh")
.arg("-o")
.arg("BatchMode=yes")
.arg(host)
.arg("-s")
.arg("sftp")
.stdin(Stdio::piped())
.stdout(Stdio::piped())
.stderr(Stdio::inherit())
.kill_on_drop(true)
.spawn()
.context("spawn ssh: is the OpenSSH client on PATH?")?;
let stdin = child.stdin.take().context("ssh stdin was not piped")?;
let stdout = child.stdout.take().context("ssh stdout was not piped")?;
Ok((
SshChild(child),
BufWriter::with_capacity(WRITE_BUF, stdin),
BufReader::new(stdout),
))
}