ssh_browser/sftp/
transport.rs1use std::process::Stdio;
9
10use anyhow::{Context, Result};
11use tokio::io::{BufReader, BufWriter};
12use tokio::process::{Child, ChildStdin, ChildStdout, Command};
13
14const WRITE_BUF: usize = 256 * 1024;
16
17pub struct SshChild(#[allow(dead_code)] Child);
20
21type Halves = (SshChild, BufWriter<ChildStdin>, BufReader<ChildStdout>);
22
23pub fn open(host: &str) -> Result<Halves> {
24 let mut child = Command::new("ssh")
25 .arg("-o")
26 .arg("BatchMode=yes")
27 .arg(host)
28 .arg("-s")
29 .arg("sftp")
30 .stdin(Stdio::piped())
31 .stdout(Stdio::piped())
32 .stderr(Stdio::inherit())
33 .kill_on_drop(true)
34 .spawn()
35 .context("spawn ssh: is the OpenSSH client on PATH?")?;
36
37 let stdin = child.stdin.take().context("ssh stdin was not piped")?;
38 let stdout = child.stdout.take().context("ssh stdout was not piped")?;
39
40 Ok((
41 SshChild(child),
42 BufWriter::with_capacity(WRITE_BUF, stdin),
43 BufReader::new(stdout),
44 ))
45}