aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJesse Luehrs <doy@tozt.net>2020-07-16 02:35:24 -0400
committerJesse Luehrs <doy@tozt.net>2020-07-16 02:35:24 -0400
commitcb611ab3142ccf3c76b2c277ede8f8c539369f67 (patch)
treeb5f127ce5580c7f0e82e1b00f27ecf7b6ceacd1f
parentb5497aa57978aa977de2848617a6d73ab2ee39ff (diff)
downloadpty-process-cb611ab3142ccf3c76b2c277ede8f8c539369f67.tar.gz
pty-process-cb611ab3142ccf3c76b2c277ede8f8c539369f67.zip
move all of the logic into the spawn method
keep the command class as a pure builder
-rw-r--r--examples/basic.rs6
-rw-r--r--src/command.rs72
2 files changed, 46 insertions, 32 deletions
diff --git a/examples/basic.rs b/examples/basic.rs
index 39ef088..6082b09 100644
--- a/examples/basic.rs
+++ b/examples/basic.rs
@@ -6,7 +6,7 @@ fn main() {
// cmd.args(&["--color=auto"]);
let mut child = cmd.spawn().unwrap();
let mut buf = [0_u8; 4096];
- let pty = cmd.pty().as_raw_fd();
+ let pty = child.pty().as_raw_fd();
let stdin = std::io::stdin().as_raw_fd();
loop {
let mut set = nix::sys::select::FdSet::new();
@@ -17,7 +17,7 @@ fn main() {
Ok(n) => {
if n > 0 {
if set.contains(pty) {
- match cmd.pty().read(&mut buf) {
+ match child.pty().read(&mut buf) {
Ok(bytes) => {
let buf = &buf[..bytes];
print!(
@@ -37,7 +37,7 @@ fn main() {
match std::io::stdin().read(&mut buf) {
Ok(bytes) => {
let buf = &buf[..bytes];
- cmd.pty().write_all(buf).unwrap();
+ child.pty().write_all(buf).unwrap();
}
Err(e) => {
eprintln!("stdin read failed: {:?}", e);
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
+ }
+}