aboutsummaryrefslogtreecommitdiffstats
path: root/src/command.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/command.rs')
-rw-r--r--src/command.rs72
1 files changed, 43 insertions, 29 deletions
diff --git a/src/command.rs b/src/command.rs
index cf01767..421f2b8 100644
--- a/src/command.rs
+++ b/src/command.rs
@@ -4,37 +4,13 @@ use std::os::unix::io::{AsRawFd as _, FromRawFd as _};
use std::os::unix::process::CommandExt as _;
pub struct Command {
- pty: crate::pty::Pty,
command: std::process::Command,
- pts_fh: Option<std::fs::File>,
}
impl Command {
pub fn new<S: AsRef<std::ffi::OsStr>>(program: S) -> Result<Self> {
- let pty = crate::pty::Pty::new()?;
- let pt_fd = pty.pt().as_raw_fd();
- let pts_fh = pty.pts()?;
- let pts_fd = pts_fh.as_raw_fd();
- let mut command = std::process::Command::new(program);
- command
- .stdin(unsafe { std::process::Stdio::from_raw_fd(pts_fd) })
- .stdout(unsafe { std::process::Stdio::from_raw_fd(pts_fd) })
- .stderr(unsafe { std::process::Stdio::from_raw_fd(pts_fd) });
- unsafe {
- command.pre_exec(move || {
- // XXX unwrap
- nix::unistd::close(pt_fd)
- .map_err(|e| e.as_errno().unwrap())?;
- nix::unistd::close(pts_fd)
- .map_err(|e| e.as_errno().unwrap())?;
- Ok(())
- });
- }
- Ok(Self {
- pty,
- command,
- pts_fh: Some(pts_fh),
- })
+ let command = std::process::Command::new(program);
+ Ok(Self { command })
}
pub fn arg<S: AsRef<std::ffi::OsStr>>(&mut self, arg: S) -> &mut Self {
@@ -101,13 +77,51 @@ impl Command {
self
}
- pub fn spawn(&mut self) -> Result<std::process::Child> {
+ pub fn spawn(&mut self) -> Result<Child> {
+ let pty = crate::pty::Pty::new()?;
+ let pt_fd = pty.pt().as_raw_fd();
+ let pts = pty.pts()?;
+ let pts_fd = pts.as_raw_fd();
+ self.command
+ .stdin(unsafe { std::process::Stdio::from_raw_fd(pts_fd) })
+ .stdout(unsafe { std::process::Stdio::from_raw_fd(pts_fd) })
+ .stderr(unsafe { std::process::Stdio::from_raw_fd(pts_fd) });
+ unsafe {
+ self.command.pre_exec(move || {
+ // XXX unwrap
+ nix::unistd::close(pt_fd)
+ .map_err(|e| e.as_errno().unwrap())?;
+ nix::unistd::close(pts_fd)
+ .map_err(|e| e.as_errno().unwrap())?;
+ Ok(())
+ });
+ }
let child = self.command.spawn()?;
- self.pts_fh = None;
- Ok(child)
+ Ok(Child { child, pty })
}
+}
+pub struct Child {
+ child: std::process::Child,
+ pty: crate::pty::Pty,
+}
+
+impl Child {
pub fn pty(&self) -> &std::fs::File {
self.pty.pt()
}
}
+
+impl std::ops::Deref for Child {
+ type Target = std::process::Child;
+
+ fn deref(&self) -> &Self::Target {
+ &self.child
+ }
+}
+
+impl std::ops::DerefMut for Child {
+ fn deref_mut(&mut self) -> &mut Self::Target {
+ &mut self.child
+ }
+}