process: add Child::{wait,try_wait} (#2796)

* add Child::try_wait to mirror the std API
* replace Future impl on Child with `.wait()` method to bring our
  APIs closer to those in std and it allow us to
  internally fuse the future so that repeated calls to `wait` result in
  the same value (similar to std) without forcing the caller to fuse the
  outer future
* Also change `Child::id` to return an Option result to avoid
  allowing the caller to accidentally use the pid on Unix systems after
  the child has been reaped
* Also remove deprecated Child methods
This commit is contained in:
Ivan Petkov
2020-09-07 03:30:40 +00:00
committed by GitHub
parent d74eabc7d7
commit 842d5565bd
9 changed files with 145 additions and 87 deletions
+24 -1
View File
@@ -72,7 +72,7 @@ async fn feed_cat(mut cat: Child, n: usize) -> io::Result<ExitStatus> {
};
// Compose reading and writing concurrently.
future::join3(write, read, cat)
future::join3(write, read, cat.wait())
.map(|(_, _, status)| status)
.await
}
@@ -125,3 +125,26 @@ async fn status_closes_any_pipes() {
assert_ok!(child.await);
}
#[tokio::test]
async fn try_wait() {
let mut child = cat().spawn().unwrap();
let id = child.id().expect("missing id");
assert!(id > 0);
assert_eq!(None, assert_ok!(child.try_wait()));
// Drop the child's stdio handles so it can terminate
drop(child.stdin.take());
drop(child.stderr.take());
drop(child.stdout.take());
assert_ok!(child.wait().await);
// test that the `.try_wait()` method is fused just like the stdlib
assert!(assert_ok!(child.try_wait()).unwrap().success());
// Can't get id after process has exited
assert_eq!(child.id(), None);
}