From e0337dbbb0a919d2bff3c22b90d0f0f17bad775d Mon Sep 17 00:00:00 2001 From: Jesse Luehrs Date: Wed, 29 Dec 2021 14:39:53 -0500 Subject: simplify --- examples/async-std.rs | 15 +++++++++------ examples/basic.rs | 25 ++++++++++++++----------- examples/interhack.rs | 23 ++++++++++------------- examples/smol.rs | 13 ++++++++----- examples/tokio.rs | 9 +++++---- src/blocking/command.rs | 45 ++++----------------------------------------- src/blocking/mod.rs | 2 +- src/command.rs | 46 ++++++---------------------------------------- src/lib.rs | 2 +- tests/basic.rs | 38 +++++++++++++++++++------------------- tests/winch.rs | 46 +++++++++++++++++++++++----------------------- 11 files changed, 100 insertions(+), 164 deletions(-) diff --git a/examples/async-std.rs b/examples/async-std.rs index 6bf9412..970841c 100644 --- a/examples/async-std.rs +++ b/examples/async-std.rs @@ -7,10 +7,13 @@ mod main { use async_std::prelude::FutureExt as _; pub async fn run( - child: &pty_process::Child, - ) -> std::result::Result<(), Box> { + child: &async_process::Child, + pty: &pty_process::Pty, + ) -> std::result::Result<(), Box> { let _raw = super::raw_guard::RawGuard::new(); + let mut input_pty = pty; + let mut output_pty = pty; let ex = async_executor::Executor::new(); let input = ex.spawn(async { @@ -19,7 +22,7 @@ mod main { loop { match stdin.read(&mut buf).await { Ok(bytes) => { - child.pty().write_all(&buf[..bytes]).await.unwrap(); + input_pty.write_all(&buf[..bytes]).await.unwrap(); } Err(e) => { eprintln!("stdin read failed: {:?}", e); @@ -32,7 +35,7 @@ mod main { let mut buf = [0_u8; 4096]; let mut stdout = async_std::io::stdout(); loop { - match child.pty().read(&mut buf).await { + match output_pty.read(&mut buf).await { Ok(bytes) => { stdout.write_all(&buf[..bytes]).await.unwrap(); stdout.flush().await.unwrap(); @@ -64,9 +67,9 @@ fn main() { pty.resize(pty_process::Size::new(24, 80)).unwrap(); let mut child = pty_process::Command::new("tac") // .args(&["500"]) - .spawn(pty) + .spawn(&pty) .unwrap(); - main::run(&child).await.unwrap(); + main::run(&child, &pty).await.unwrap(); child.status().await.unwrap() }); std::process::exit( diff --git a/examples/basic.rs b/examples/basic.rs index c9b5f6c..4f996b9 100644 --- a/examples/basic.rs +++ b/examples/basic.rs @@ -4,16 +4,19 @@ mod main { use std::io::{Read as _, Write as _}; use std::os::unix::io::AsRawFd as _; - pub fn run(child: &mut pty_process::blocking::Child) { + pub fn run( + child: &mut std::process::Child, + mut pty: &pty_process::blocking::Pty, + ) { let _raw = super::raw_guard::RawGuard::new(); let mut buf = [0_u8; 4096]; - let pty = child.pty().as_raw_fd(); - let stdin = std::io::stdin().as_raw_fd(); + let pty_fd = pty.as_raw_fd(); + let stdin_fd = std::io::stdin().as_raw_fd(); loop { let mut set = nix::sys::select::FdSet::new(); - set.insert(pty); - set.insert(stdin); + set.insert(pty_fd); + set.insert(stdin_fd); match nix::sys::select::select( None, Some(&mut set), @@ -23,8 +26,8 @@ mod main { ) { Ok(n) => { if n > 0 { - if set.contains(pty) { - match child.pty().read(&mut buf) { + if set.contains(pty_fd) { + match pty.read(&mut buf) { Ok(bytes) => { let buf = &buf[..bytes]; let stdout = std::io::stdout(); @@ -38,11 +41,11 @@ mod main { } }; } - if set.contains(stdin) { + if set.contains(stdin_fd) { match std::io::stdin().read(&mut buf) { Ok(bytes) => { let buf = &buf[..bytes]; - child.pty().write_all(buf).unwrap(); + pty.write_all(buf).unwrap(); } Err(e) => { eprintln!("stdin read failed: {:?}", e); @@ -76,10 +79,10 @@ fn main() { pty.resize(pty_process::Size::new(24, 80)).unwrap(); let mut child = pty_process::blocking::Command::new("tac") // .args(&["500"]) - .spawn(pty) + .spawn(&pty) .unwrap(); - main::run(&mut child); + main::run(&mut child, &pty); let status = child.wait().unwrap(); std::process::exit( diff --git a/examples/interhack.rs b/examples/interhack.rs index 9d44bbf..212c12e 100644 --- a/examples/interhack.rs +++ b/examples/interhack.rs @@ -5,10 +5,13 @@ mod main { use smol::io::{AsyncReadExt as _, AsyncWriteExt as _}; pub async fn run( - child: &pty_process::Child, + child: &async_process::Child, + pty: &pty_process::Pty, ) -> std::result::Result<(), Box> { let _raw = super::raw_guard::RawGuard::new(); + let mut input_pty = pty; + let mut output_pty = pty; let ex = smol::Executor::new(); let input = ex.spawn(async { @@ -21,24 +24,18 @@ mod main { if buf[..bytes].contains(&5u8) { for byte in buf[..bytes].iter() { match byte { - 5u8 => child - .pty() + 5u8 => input_pty .write_all(b"E- Elbereth\n") .await .unwrap(), - _ => child - .pty() + _ => input_pty .write_all(&[*byte]) .await .unwrap(), } } } else { - child - .pty() - .write_all(&buf[..bytes]) - .await - .unwrap(); + input_pty.write_all(&buf[..bytes]).await.unwrap(); } } Err(e) => { @@ -54,7 +51,7 @@ mod main { #[allow(clippy::trivial_regex)] let re = regex::bytes::Regex::new("Elbereth").unwrap(); loop { - match child.pty().read(&mut buf).await { + match output_pty.read(&mut buf).await { Ok(bytes) => { // highlight successful Elbereths if re.is_match(&buf[..bytes]) { @@ -102,8 +99,8 @@ fn main() { let pty = pty_process::Pty::new().unwrap(); pty.resize(pty_process::Size::new(h, w)).unwrap(); let mut child = - pty_process::Command::new("nethack").spawn(pty).unwrap(); - main::run(&child).await.unwrap(); + pty_process::Command::new("nethack").spawn(&pty).unwrap(); + main::run(&child, &pty).await.unwrap(); child.status().await.unwrap() }); std::process::exit( diff --git a/examples/smol.rs b/examples/smol.rs index e8b1c4c..651ff10 100644 --- a/examples/smol.rs +++ b/examples/smol.rs @@ -5,10 +5,13 @@ mod main { use smol::io::{AsyncReadExt as _, AsyncWriteExt as _}; pub async fn run( - child: &pty_process::Child, + child: &async_process::Child, + pty: &pty_process::Pty, ) -> std::result::Result<(), Box> { let _raw = super::raw_guard::RawGuard::new(); + let mut input_pty = pty; + let mut output_pty = pty; let ex = smol::Executor::new(); let input = ex.spawn(async { @@ -17,7 +20,7 @@ mod main { loop { match stdin.read(&mut buf).await { Ok(bytes) => { - child.pty().write_all(&buf[..bytes]).await.unwrap(); + input_pty.write_all(&buf[..bytes]).await.unwrap(); } Err(e) => { eprintln!("stdin read failed: {:?}", e); @@ -30,7 +33,7 @@ mod main { let mut buf = [0_u8; 4096]; let mut stdout = smol::Unblock::new(std::io::stdout()); loop { - match child.pty().read(&mut buf).await { + match output_pty.read(&mut buf).await { Ok(bytes) => { stdout.write_all(&buf[..bytes]).await.unwrap(); stdout.flush().await.unwrap(); @@ -63,9 +66,9 @@ fn main() { pty.resize(pty_process::Size::new(24, 80)).unwrap(); let mut child = pty_process::Command::new("tac") // .args(&["500"]) - .spawn(pty) + .spawn(&pty) .unwrap(); - main::run(&child).await.unwrap(); + main::run(&child, &pty).await.unwrap(); child.status().await.unwrap() }); std::process::exit( diff --git a/examples/tokio.rs b/examples/tokio.rs index 16083c7..55436c2 100644 --- a/examples/tokio.rs +++ b/examples/tokio.rs @@ -6,7 +6,8 @@ mod main { use tokio_util::compat::FuturesAsyncReadCompatExt as _; pub async fn run( - child: &pty_process::Child, + child: &async_process::Child, + pty: &pty_process::Pty, ) -> std::result::Result<(), Box> { let _raw = super::raw_guard::RawGuard::new(); @@ -15,9 +16,9 @@ mod main { let mut stdin = tokio::io::stdin(); let mut stdout = tokio::io::stdout(); + let mut pty = pty.compat(); loop { - let mut pty = child.pty().compat(); tokio::select! { bytes = stdin.read(&mut in_buf) => match bytes { Ok(bytes) => { @@ -55,9 +56,9 @@ async fn main() { pty.resize(pty_process::Size::new(24, 80)).unwrap(); let mut child = pty_process::Command::new("tac") // .args(&["500"]) - .spawn(pty) + .spawn(&pty) .unwrap(); - main::run(&child).await.unwrap(); + main::run(&child, &pty).await.unwrap(); let status = child.status().await.unwrap(); std::process::exit( status diff --git a/src/blocking/command.rs b/src/blocking/command.rs index cc3419a..54a5e37 100644 --- a/src/blocking/command.rs +++ b/src/blocking/command.rs @@ -97,10 +97,10 @@ impl Command { pub fn spawn( &mut self, - pty: crate::blocking::Pty, - ) -> crate::Result { + pty: &crate::blocking::Pty, + ) -> crate::Result { let (stdin, stdout, stderr, 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)); @@ -111,43 +111,6 @@ impl Command { // async-signal-safe). unsafe { self.inner.pre_exec(pre_exec) }; - let child = self.inner.spawn()?; - - Ok(Child::new(child, pty)) - } -} - -pub struct Child { - inner: std::process::Child, - pty: crate::blocking::Pty, -} - -impl Child { - fn new(inner: std::process::Child, pty: crate::blocking::Pty) -> Self { - Self { inner, pty } - } - - #[must_use] - pub fn pty(&self) -> &crate::blocking::Pty { - &self.pty - } - - #[must_use] - pub fn pty_mut(&mut self) -> &mut crate::blocking::Pty { - &mut self.pty - } -} - -impl std::ops::Deref for Child { - type Target = std::process::Child; - - fn deref(&self) -> &Self::Target { - &self.inner - } -} - -impl std::ops::DerefMut for Child { - fn deref_mut(&mut self) -> &mut Self::Target { - &mut self.inner + Ok(self.inner.spawn()?) } } diff --git a/src/blocking/mod.rs b/src/blocking/mod.rs index a45b132..cdf66da 100644 --- a/src/blocking/mod.rs +++ b/src/blocking/mod.rs @@ -1,4 +1,4 @@ mod command; -pub use command::{Child, Command}; +pub use command::Command; mod pty; pub use pty::Pty; diff --git a/src/command.rs b/src/command.rs index ef156aa..18e1f17 100644 --- a/src/command.rs +++ b/src/command.rs @@ -95,9 +95,12 @@ impl Command { self } - pub fn spawn(&mut self, pty: crate::Pty) -> crate::Result { + pub fn spawn( + &mut self, + pty: &crate::Pty, + ) -> crate::Result { let (stdin, stdout, stderr, 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)); @@ -108,43 +111,6 @@ impl Command { // async-signal-safe). unsafe { self.inner.pre_exec(pre_exec) }; - let child = self.inner.spawn()?; - - Ok(Child::new(child, pty)) - } -} - -pub struct Child { - inner: async_process::Child, - pty: crate::Pty, -} - -impl Child { - fn new(inner: async_process::Child, pty: crate::Pty) -> Self { - Self { inner, pty } - } - - #[must_use] - pub fn pty(&self) -> &crate::Pty { - &self.pty - } - - #[must_use] - pub fn pty_mut(&mut self) -> &mut crate::Pty { - &mut self.pty - } -} - -impl std::ops::Deref for Child { - type Target = async_process::Child; - - fn deref(&self) -> &Self::Target { - &self.inner - } -} - -impl std::ops::DerefMut for Child { - fn deref_mut(&mut self) -> &mut Self::Target { - &mut self.inner + Ok(self.inner.spawn()?) } } diff --git a/src/lib.rs b/src/lib.rs index 3f7577f..efb12de 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -23,7 +23,7 @@ pub mod blocking; #[cfg(feature = "async")] mod command; #[cfg(feature = "async")] -pub use command::{Child, Command}; +pub use command::Command; #[cfg(feature = "async")] mod pty; #[cfg(feature = "async")] diff --git a/tests/basic.rs b/tests/basic.rs index a623f13..f73b39e 100644 --- a/tests/basic.rs +++ b/tests/basic.rs @@ -2,13 +2,13 @@ fn test_cat_blocking() { use std::io::{Read as _, Write as _}; - let pty = pty_process::blocking::Pty::new().unwrap(); + 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("cat") - .spawn(pty) + .spawn(&pty) .unwrap(); - child.pty().write_all(b"foo\n").unwrap(); + pty.write_all(b"foo\n").unwrap(); // the pty will echo the written bytes back immediately, but the // subprocess needs to generate its own output, which takes time, so we // can't just read immediately (we may just get the echoed bytes). because @@ -18,10 +18,10 @@ fn test_cat_blocking() { std::thread::sleep(std::time::Duration::from_secs(1)); let mut buf = [0u8; 1024]; - let bytes = child.pty().read(&mut buf).unwrap(); + let bytes = pty.read(&mut buf).unwrap(); assert_eq!(&buf[..bytes], b"foo\r\nfoo\r\n"); - child.pty().write_all(&[4u8]).unwrap(); + pty.write_all(&[4u8]).unwrap(); let status = child.wait().unwrap(); assert_eq!(status.code().unwrap(), 0); } @@ -33,11 +33,11 @@ fn test_cat_async_std() { use async_std::io::ReadExt as _; let status = async_std::task::block_on(async { - let pty = pty_process::Pty::new().unwrap(); + let mut pty = pty_process::Pty::new().unwrap(); pty.resize(pty_process::Size::new(24, 80)).unwrap(); - let mut child = pty_process::Command::new("cat").spawn(pty).unwrap(); + let mut child = pty_process::Command::new("cat").spawn(&pty).unwrap(); - child.pty().write_all(b"foo\n").await.unwrap(); + pty.write_all(b"foo\n").await.unwrap(); // the pty will echo the written bytes back immediately, but the // subprocess needs to generate its own output, which takes time, so // we can't just read immediately (we may just get the echoed bytes). @@ -47,10 +47,10 @@ fn test_cat_async_std() { async_std::task::sleep(std::time::Duration::from_secs(1)).await; let mut buf = [0u8; 1024]; - let bytes = child.pty().read(&mut buf).await.unwrap(); + let bytes = pty.read(&mut buf).await.unwrap(); assert_eq!(&buf[..bytes], b"foo\r\nfoo\r\n"); - child.pty().write_all(&[4u8]).await.unwrap(); + pty.write_all(&[4u8]).await.unwrap(); child.status().await.unwrap() }); assert_eq!(status.code().unwrap(), 0); @@ -62,11 +62,11 @@ fn test_cat_smol() { use smol::io::{AsyncReadExt as _, AsyncWriteExt as _}; let status = smol::block_on(async { - let pty = pty_process::Pty::new().unwrap(); + let mut pty = pty_process::Pty::new().unwrap(); pty.resize(pty_process::Size::new(24, 80)).unwrap(); - let mut child = pty_process::Command::new("cat").spawn(pty).unwrap(); + let mut child = pty_process::Command::new("cat").spawn(&pty).unwrap(); - child.pty().write_all(b"foo\n").await.unwrap(); + pty.write_all(b"foo\n").await.unwrap(); // the pty will echo the written bytes back immediately, but the // subprocess needs to generate its own output, which takes time, so // we can't just read immediately (we may just get the echoed bytes). @@ -76,10 +76,10 @@ fn test_cat_smol() { smol::Timer::after(std::time::Duration::from_secs(1)).await; let mut buf = [0u8; 1024]; - let bytes = child.pty().read(&mut buf).await.unwrap(); + let bytes = pty.read(&mut buf).await.unwrap(); assert_eq!(&buf[..bytes], b"foo\r\nfoo\r\n"); - child.pty().write_all(&[4u8]).await.unwrap(); + pty.write_all(&[4u8]).await.unwrap(); child.status().await.unwrap() }); assert_eq!(status.code().unwrap(), 0); @@ -94,9 +94,9 @@ fn test_cat_tokio() { async fn async_test_cat_tokio() { let pty = pty_process::Pty::new().unwrap(); pty.resize(pty_process::Size::new(24, 80)).unwrap(); - let mut child = pty_process::Command::new("cat").spawn(pty).unwrap(); + let mut child = pty_process::Command::new("cat").spawn(&pty).unwrap(); - child.pty_mut().compat().write_all(b"foo\n").await.unwrap(); + pty.compat().write_all(b"foo\n").await.unwrap(); // the pty will echo the written bytes back immediately, but the // subprocess needs to generate its own output, which takes time, so // we can't just read immediately (we may just get the echoed bytes). @@ -106,10 +106,10 @@ fn test_cat_tokio() { tokio::time::sleep(std::time::Duration::from_secs(1)).await; let mut buf = [0u8; 1024]; - let bytes = child.pty_mut().compat().read(&mut buf).await.unwrap(); + let bytes = pty.compat().read(&mut buf).await.unwrap(); assert_eq!(&buf[..bytes], b"foo\r\nfoo\r\n"); - child.pty_mut().compat().write_all(&[4u8]).await.unwrap(); + pty.compat().write_all(&[4u8]).await.unwrap(); let status = child.status().await.unwrap(); assert_eq!(status.code().unwrap(), 0); diff --git a/tests/winch.rs b/tests/winch.rs index 9d26751..40ffaf4 100644 --- a/tests/winch.rs +++ b/tests/winch.rs @@ -2,26 +2,26 @@ fn test_winch_std() { use std::io::{Read as _, Write as _}; - let pty = pty_process::blocking::Pty::new().unwrap(); + 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("perl") .args(&[ "-E", "$|++; $SIG{WINCH} = sub { say 'WINCH' }; say 'started'; <>", ]) - .spawn(pty) + .spawn(&pty) .unwrap(); let mut buf = [0u8; 1024]; - let bytes = child.pty().read(&mut buf).unwrap(); + let bytes = pty.read(&mut buf).unwrap(); assert_eq!(&buf[..bytes], b"started\r\n"); - child.pty().resize(pty_process::Size::new(25, 80)).unwrap(); + pty.resize(pty_process::Size::new(25, 80)).unwrap(); - let bytes = child.pty().read(&mut buf).unwrap(); + let bytes = pty.read(&mut buf).unwrap(); assert_eq!(&buf[..bytes], b"WINCH\r\n"); - child.pty().write_all(b"\n").unwrap(); + pty.write_all(b"\n").unwrap(); let status = child.wait().unwrap(); assert_eq!(status.code().unwrap(), 0); } @@ -33,26 +33,26 @@ fn test_winch_async_std() { use async_std::io::ReadExt as _; let status = async_std::task::block_on(async { - let pty = pty_process::Pty::new().unwrap(); + let mut pty = pty_process::Pty::new().unwrap(); pty.resize(pty_process::Size::new(24, 80)).unwrap(); let mut child = pty_process::Command::new("perl") .args(&[ "-E", "$|++; $SIG{WINCH} = sub { say 'WINCH' }; say 'started'; <>", ]) - .spawn(pty) + .spawn(&pty) .unwrap(); let mut buf = [0u8; 1024]; - let bytes = child.pty().read(&mut buf).await.unwrap(); + let bytes = pty.read(&mut buf).await.unwrap(); assert_eq!(&buf[..bytes], b"started\r\n"); - child.pty().resize(pty_process::Size::new(25, 80)).unwrap(); + pty.resize(pty_process::Size::new(25, 80)).unwrap(); - let bytes = child.pty().read(&mut buf).await.unwrap(); + let bytes = pty.read(&mut buf).await.unwrap(); assert_eq!(&buf[..bytes], b"WINCH\r\n"); - child.pty().write_all(b"\n").await.unwrap(); + pty.write_all(b"\n").await.unwrap(); child.status().await.unwrap() }); assert_eq!(status.code().unwrap(), 0); @@ -64,26 +64,26 @@ fn test_winch_smol() { use smol::io::{AsyncReadExt as _, AsyncWriteExt as _}; let status = smol::block_on(async { - let pty = pty_process::Pty::new().unwrap(); + let mut pty = pty_process::Pty::new().unwrap(); pty.resize(pty_process::Size::new(24, 80)).unwrap(); let mut child = pty_process::Command::new("perl") .args(&[ "-E", "$|++; $SIG{WINCH} = sub { say 'WINCH' }; say 'started'; <>", ]) - .spawn(pty) + .spawn(&pty) .unwrap(); let mut buf = [0u8; 1024]; - let bytes = child.pty().read(&mut buf).await.unwrap(); + let bytes = pty.read(&mut buf).await.unwrap(); assert_eq!(&buf[..bytes], b"started\r\n"); - child.pty().resize(pty_process::Size::new(25, 80)).unwrap(); + pty.resize(pty_process::Size::new(25, 80)).unwrap(); - let bytes = child.pty().read(&mut buf).await.unwrap(); + let bytes = pty.read(&mut buf).await.unwrap(); assert_eq!(&buf[..bytes], b"WINCH\r\n"); - child.pty().write_all(b"\n").await.unwrap(); + pty.write_all(b"\n").await.unwrap(); child.status().await.unwrap() }); assert_eq!(status.code().unwrap(), 0); @@ -103,19 +103,19 @@ fn test_winch_tokio() { "-E", "$|++; $SIG{WINCH} = sub { say 'WINCH' }; say 'started'; <>", ]) - .spawn(pty) + .spawn(&pty) .unwrap(); let mut buf = [0u8; 1024]; - let bytes = child.pty().compat().read(&mut buf).await.unwrap(); + let bytes = pty.compat().read(&mut buf).await.unwrap(); assert_eq!(&buf[..bytes], b"started\r\n"); - child.pty().resize(pty_process::Size::new(25, 80)).unwrap(); + pty.resize(pty_process::Size::new(25, 80)).unwrap(); - let bytes = child.pty().compat().read(&mut buf).await.unwrap(); + let bytes = pty.compat().read(&mut buf).await.unwrap(); assert_eq!(&buf[..bytes], b"WINCH\r\n"); - child.pty().compat().write_all(b"\n").await.unwrap(); + pty.compat().write_all(b"\n").await.unwrap(); child.status().await.unwrap() } tokio::runtime::Runtime::new().unwrap().block_on(async { -- cgit v1.2.3-54-g00ecf