From f1779c4549c88e7996031b7211a556e8e4b54963 Mon Sep 17 00:00:00 2001 From: Jesse Luehrs Date: Wed, 29 Dec 2021 21:38:22 -0500 Subject: i don't think we need to open pts multiple times? --- src/blocking/command.rs | 2 +- src/blocking/pty.rs | 16 ++++++++-------- src/command.rs | 2 +- src/pty.rs | 16 ++++++++-------- src/sys.rs | 4 ++-- tests/multiple.rs | 27 +++++++++++++++++++++++++++ 6 files changed, 47 insertions(+), 20 deletions(-) create mode 100644 tests/multiple.rs diff --git a/src/blocking/command.rs b/src/blocking/command.rs index 0460add..0ec55db 100644 --- a/src/blocking/command.rs +++ b/src/blocking/command.rs @@ -104,7 +104,7 @@ impl Command { pty: &crate::blocking::Pty, ) -> crate::Result { let (stdin, stdout, stderr, mut pre_exec) = - crate::sys::setup_subprocess(pty, pty.pts()?)?; + crate::sys::setup_subprocess(pty, pty.pts())?; self.inner.stdin(self.stdin.take().unwrap_or(stdin)); self.inner.stdout(self.stdout.take().unwrap_or(stdout)); diff --git a/src/blocking/pty.rs b/src/blocking/pty.rs index 6b1a2a3..d864bd6 100644 --- a/src/blocking/pty.rs +++ b/src/blocking/pty.rs @@ -1,24 +1,24 @@ pub struct Pty { pt: std::fs::File, - ptsname: std::path::PathBuf, + pts: std::fs::File, } impl Pty { pub fn new() -> crate::Result { let (pt, ptsname) = crate::sys::create_pt()?; - Ok(Self { pt, ptsname }) + let pts = std::fs::OpenOptions::new() + .read(true) + .write(true) + .open(&ptsname)?; + Ok(Self { pt, pts }) } pub fn resize(&self, size: crate::Size) -> crate::Result<()> { Ok(crate::sys::set_term_size(self, size)?) } - pub(crate) fn pts(&self) -> std::io::Result { - let fh = std::fs::OpenOptions::new() - .read(true) - .write(true) - .open(&self.ptsname)?; - Ok(fh) + pub(crate) fn pts(&self) -> &std::fs::File { + &self.pts } } diff --git a/src/command.rs b/src/command.rs index 3867bf2..171e764 100644 --- a/src/command.rs +++ b/src/command.rs @@ -104,7 +104,7 @@ impl Command { pty: &crate::Pty, ) -> crate::Result { let (stdin, stdout, stderr, mut pre_exec) = - crate::sys::setup_subprocess(pty, pty.pts()?)?; + crate::sys::setup_subprocess(pty, pty.pts())?; self.inner.stdin(self.stdin.take().unwrap_or(stdin)); self.inner.stdout(self.stdout.take().unwrap_or(stdout)); diff --git a/src/pty.rs b/src/pty.rs index 64cb12c..5d398d4 100644 --- a/src/pty.rs +++ b/src/pty.rs @@ -1,25 +1,25 @@ pub struct Pty { pt: async_io::Async, - ptsname: std::path::PathBuf, + pts: std::fs::File, } impl Pty { pub fn new() -> crate::Result { let (pt, ptsname) = crate::sys::create_pt()?; let pt = async_io::Async::new(pt)?; - Ok(Self { pt, ptsname }) + let pts = std::fs::OpenOptions::new() + .read(true) + .write(true) + .open(&ptsname)?; + Ok(Self { pt, pts }) } pub fn resize(&self, size: crate::Size) -> crate::Result<()> { Ok(crate::sys::set_term_size(self, size)?) } - pub(crate) fn pts(&self) -> std::io::Result { - let fh = std::fs::OpenOptions::new() - .read(true) - .write(true) - .open(&self.ptsname)?; - Ok(fh) + pub(crate) fn pts(&self) -> &std::fs::File { + &self.pts } } diff --git a/src/sys.rs b/src/sys.rs index 9cf6a44..03a5428 100644 --- a/src/sys.rs +++ b/src/sys.rs @@ -40,7 +40,7 @@ pub fn set_term_size( pub fn setup_subprocess( pt: &impl std::os::unix::io::AsRawFd, - pts: impl std::os::unix::io::IntoRawFd, + pts: &impl std::os::unix::io::AsRawFd, ) -> nix::Result<( std::process::Stdio, std::process::Stdio, @@ -48,7 +48,7 @@ pub fn setup_subprocess( impl FnMut() -> std::io::Result<()>, )> { let pt_fd = pt.as_raw_fd(); - let pts_fd = pts.into_raw_fd(); + let pts_fd = pts.as_raw_fd(); let stdin = nix::unistd::dup(pts_fd)?; let stdout = nix::unistd::dup(pts_fd)?; diff --git a/tests/multiple.rs b/tests/multiple.rs new file mode 100644 index 0000000..8d96050 --- /dev/null +++ b/tests/multiple.rs @@ -0,0 +1,27 @@ +#[test] +fn test_multiple() { + use std::io::Read as _; + + let mut pty = pty_process::blocking::Pty::new().unwrap(); + pty.resize(pty_process::Size::new(24, 80)).unwrap(); + + let mut child = pty_process::blocking::Command::new("echo") + .arg("foo") + .spawn(&pty) + .unwrap(); + let mut buf = [0u8; 1024]; + let bytes = pty.read(&mut buf).unwrap(); + assert_eq!(&buf[..bytes], b"foo\r\n"); + let status = child.wait().unwrap(); + assert_eq!(status.code().unwrap(), 0); + + let mut child = pty_process::blocking::Command::new("echo") + .arg("bar") + .spawn(&pty) + .unwrap(); + let mut buf = [0u8; 1024]; + let bytes = pty.read(&mut buf).unwrap(); + assert_eq!(&buf[..bytes], b"bar\r\n"); + let status = child.wait().unwrap(); + assert_eq!(status.code().unwrap(), 0); +} -- cgit v1.2.3-54-g00ecf