openssh/process_impl/
child.rs

1use super::Error;
2
3use std::io;
4use std::process::ExitStatus;
5
6use tokio::process;
7
8// Disconnects the ssh session at drop, but does not kill the remote process.
9#[derive(Debug)]
10pub(crate) struct RemoteChild {
11    channel: process::Child,
12}
13
14impl RemoteChild {
15    /// * `channel` - Must be created with `process::Command::kill_on_drop(true)`.
16    pub(crate) fn new(channel: process::Child) -> Self {
17        Self { channel }
18    }
19
20    pub(crate) async fn disconnect(mut self) -> io::Result<()> {
21        // this disconnects, but does not kill the remote process
22        self.channel.kill().await?;
23
24        Ok(())
25    }
26
27    pub(crate) async fn wait(mut self) -> Result<ExitStatus, Error> {
28        match self.channel.wait().await {
29            Err(e) => Err(Error::Remote(e)),
30            Ok(w) => match w.code() {
31                Some(255) => Err(Error::RemoteProcessTerminated),
32                Some(127) => Err(Error::Remote(io::Error::new(
33                    io::ErrorKind::NotFound,
34                    "remote command not found",
35                ))),
36                _ => Ok(w),
37            },
38        }
39    }
40}