From 61e10f81bec218b879c5f39b3b19ef1fd2af2db4 Mon Sep 17 00:00:00 2001 From: Jesse Luehrs <doy@tozt.net> Date: Wed, 22 Dec 2021 20:20:00 -0500 Subject: [PATCH 1/2] make try_status take &self it doesn't need exclusive access --- src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index ed10784..9678d8c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -326,7 +326,7 @@ impl Child { /// } /// # std::io::Result::Ok(()) }); /// ``` - pub fn try_status(&mut self) -> io::Result<Option<ExitStatus>> { + pub fn try_status(&self) -> io::Result<Option<ExitStatus>> { self.child.lock().unwrap().get_mut().try_wait() } From 4438e61dac21d58c29ab4cc7d8152c829977a62d Mon Sep 17 00:00:00 2001 From: Jesse Luehrs <doy@tozt.net> Date: Wed, 22 Dec 2021 20:25:56 -0500 Subject: [PATCH 2/2] add status_no_drop which takes &self and doesn't drop stdin this is a much more useful capability for an async process library, since it is much easier to avoid blocking on this call (since it is a future) --- src/lib.rs | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/lib.rs b/src/lib.rs index 9678d8c..cf005e1 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -352,6 +352,30 @@ impl Child { /// ``` pub fn status(&mut self) -> impl Future<Output = io::Result<ExitStatus>> { self.stdin.take(); + self.status_no_drop() + } + + /// Waits for the process to exit. + /// + /// Unlike `status`, does not drop the stdin handle. You are responsible + /// for avoiding deadlocks caused by the child blocking on stdin while the + /// parent blocks on waiting for the process to exit. + /// + /// # Examples + /// + /// ```no_run + /// # futures_lite::future::block_on(async { + /// use async_process::{Command, Stdio}; + /// + /// let child = Command::new("cp") + /// .arg("a.txt") + /// .arg("b.txt") + /// .spawn()?; + /// + /// println!("exit status: {}", child.status_no_drop().await?); + /// # std::io::Result::Ok(()) }); + /// ``` + pub fn status_no_drop(&self) -> impl Future<Output = io::Result<ExitStatus>> { let child = self.child.clone(); async move {