aboutsummaryrefslogtreecommitdiffstats
path: root/src/command.rs
blob: b2d8ef7fe57982d6a6aec5a31095a7b0a40b986f (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
use crate::error::*;

use std::os::unix::io::{AsRawFd as _, FromRawFd as _};

pub struct Command {
    pty: crate::pty::Pty,
    command: std::process::Command,
}

impl Command {
    pub fn new<S: std::convert::AsRef<std::ffi::OsStr>>(
        program: S,
    ) -> Result<Self> {
        let pty = crate::pty::Pty::new()?;
        let fd = pty.master().as_raw_fd();
        let stdin = unsafe { std::process::Stdio::from_raw_fd(fd) };
        let stdout = unsafe { std::process::Stdio::from_raw_fd(fd) };
        let stderr = unsafe { std::process::Stdio::from_raw_fd(fd) };
        let mut command = std::process::Command::new(program);
        command.stdin(stdin).stdout(stdout).stderr(stderr);
        Ok(Self { pty, command })
    }

    pub fn pty(&self) -> &std::fs::File {
        self.pty.slave()
    }
}

impl std::ops::Deref for Command {
    type Target = std::process::Command;

    fn deref(&self) -> &Self::Target {
        &self.command
    }
}

impl std::ops::DerefMut for Command {
    fn deref_mut(&mut self) -> &mut Self::Target {
        &mut self.command
    }
}