signal: remove new() constructors in favor of free functions (#1472)

* Also removed any `*_with_handle` related methods in favor of always
using the default reactor
This commit is contained in:
Ivan Petkov
2019-08-18 14:22:09 -07:00
committed by GitHub
parent 7b0c60849c
commit 08b07afbd9
15 changed files with 104 additions and 234 deletions
+3 -70
View File
@@ -146,7 +146,6 @@ use futures_util::try_future::TryFutureExt;
use kill::Kill;
use tokio_io::{AsyncRead, AsyncReadExt, AsyncWrite};
use tokio_net::driver::Handle;
#[path = "unix/mod.rs"]
#[cfg(unix)]
@@ -493,24 +492,7 @@ impl Command {
/// .expect("ls command failed to run")
/// }
pub fn spawn(&mut self) -> io::Result<Child> {
self.spawn_with_handle(&Handle::default())
}
/// Executes the command as a child process, returning a handle to it.
///
/// By default, stdin, stdout and stderr are inherited from the parent.
///
/// This method will spawn the child process synchronously and return a
/// handle to a future-aware child process. The `Child` returned implements
/// `Future` itself to acquire the `ExitStatus` of the child, and otherwise
/// the `Child` has methods to acquire handles to the stdin, stdout, and
/// stderr streams.
///
/// The `handle` specified to this method must be a handle to a valid event
/// loop, and all I/O this child does will be associated with the specified
/// event loop.
pub fn spawn_with_handle(&mut self, handle: &Handle) -> io::Result<Child> {
imp::spawn_child(&mut self.std, handle).map(|spawned_child| Child {
imp::spawn_child(&mut self.std).map(|spawned_child| Child {
child: ChildDropGuard::new(spawned_child.child),
stdin: spawned_child.stdin.map(|inner| ChildStdin { inner }),
stdout: spawned_child.stdout.map(|inner| ChildStdout { inner }),
@@ -556,32 +538,7 @@ impl Command {
/// .expect("ls command failed to run")
/// }
pub fn status(&mut self) -> io::Result<StatusAsync> {
self.status_with_handle(&Handle::default())
}
/// Executes a command as a child process, waiting for it to finish and
/// collecting its exit status.
///
/// By default, stdin, stdout and stderr are inherited from the parent.
///
/// The `StatusAsync` future returned will resolve to the `ExitStatus`
/// type in the standard library representing how the process exited. If
/// any input/output handles are set to a pipe then they will be immediately
/// closed after the child is spawned.
///
/// The `handle` specified must be a handle to a valid event loop, and all
/// I/O this child does will be associated with the specified event loop.
///
/// If the `StatusAsync` future is dropped before the future resolves, then
/// the child will be killed, if it was spawned.
///
/// # Errors
///
/// This function will return an error immediately if the child process
/// cannot be spawned. Otherwise errors obtained while waiting for the child
/// are returned through the `StatusAsync` future.
pub fn status_with_handle(&mut self, handle: &Handle) -> io::Result<StatusAsync> {
self.spawn_with_handle(handle).map(|mut child| {
self.spawn().map(|mut child| {
// Ensure we close any stdio handles so we can't deadlock
// waiting on the child which may be waiting to read/write
// to a pipe we're holding.
@@ -630,34 +587,10 @@ impl Command {
/// println!("stderr of ls: {:?}", output.stderr);
/// }
pub fn output(&mut self) -> OutputAsync {
self.output_with_handle(&Handle::default())
}
/// Executes the command as a child process, waiting for it to finish and
/// collecting all of its output.
///
/// > **Note**: this method, unlike the standard library, will
/// > unconditionally configure the stdout/stderr handles to be pipes, even
/// > if they have been previously configured. If this is not desired then
/// > the `spawn` method should be used in combination with the
/// > `wait_with_output` method on child.
///
/// This method will return a future representing the collection of the
/// child process's stdout/stderr. The `OutputAsync` future will resolve to
/// the `Output` type in the standard library, containing `stdout` and
/// `stderr` as `Vec<u8>` along with an `ExitStatus` representing how the
/// process exited.
///
/// The `handle` specified must be a handle to a valid event loop, and all
/// I/O this child does will be associated with the specified event loop.
///
/// If the `OutputAsync` future is dropped before the future resolves, then
/// the child will be killed, if it was spawned.
pub fn output_with_handle(&mut self, handle: &Handle) -> OutputAsync {
self.std.stdout(Stdio::piped());
self.std.stderr(Stdio::piped());
let inner = future::ready(self.spawn_with_handle(handle)).and_then(Child::wait_with_output);
let inner = future::ready(self.spawn()).and_then(Child::wait_with_output);
OutputAsync {
inner: inner.boxed(),
+8 -10
View File
@@ -29,8 +29,7 @@ use self::reap::Reaper;
use super::SpawnedChild;
use crate::kill::Kill;
use tokio_net::driver::Handle;
use tokio_net::signal::unix::{Signal, SignalKind};
use tokio_net::signal::unix::{signal, Signal, SignalKind};
use tokio_net::util::PollEvented;
use mio::event::Evented;
@@ -96,13 +95,13 @@ impl fmt::Debug for Child {
}
}
pub(crate) fn spawn_child(cmd: &mut process::Command, handle: &Handle) -> io::Result<SpawnedChild> {
pub(crate) fn spawn_child(cmd: &mut process::Command) -> io::Result<SpawnedChild> {
let mut child = cmd.spawn()?;
let stdin = stdio(child.stdin.take(), handle)?;
let stdout = stdio(child.stdout.take(), handle)?;
let stderr = stdio(child.stderr.take(), handle)?;
let stdin = stdio(child.stdin.take())?;
let stdout = stdio(child.stdout.take())?;
let stderr = stdio(child.stderr.take())?;
let signal = Signal::with_handle(SignalKind::child(), handle)?;
let signal = signal(SignalKind::child())?;
Ok(SpawnedChild {
child: Child {
@@ -203,7 +202,7 @@ pub(crate) type ChildStdin = PollEvented<Fd<process::ChildStdin>>;
pub(crate) type ChildStdout = PollEvented<Fd<process::ChildStdout>>;
pub(crate) type ChildStderr = PollEvented<Fd<process::ChildStderr>>;
fn stdio<T>(option: Option<T>, handle: &Handle) -> io::Result<Option<PollEvented<Fd<T>>>>
fn stdio<T>(option: Option<T>) -> io::Result<Option<PollEvented<Fd<T>>>>
where
T: AsRawFd,
{
@@ -224,6 +223,5 @@ where
return Err(io::Error::last_os_error());
}
}
let io = PollEvented::new_with_handle(Fd { inner: io }, handle)?;
Ok(Some(io))
Ok(Some(PollEvented::new(Fd { inner: io })))
}
+7 -9
View File
@@ -18,7 +18,6 @@
use super::SpawnedChild;
use crate::kill::Kill;
use tokio_net::driver::Handle;
use tokio_net::util::PollEvented;
use tokio_sync::oneshot;
@@ -69,11 +68,11 @@ struct Waiting {
unsafe impl Sync for Waiting {}
unsafe impl Send for Waiting {}
pub(crate) fn spawn_child(cmd: &mut process::Command, handle: &Handle) -> io::Result<SpawnedChild> {
pub(crate) fn spawn_child(cmd: &mut process::Command) -> io::Result<SpawnedChild> {
let mut child = cmd.spawn()?;
let stdin = stdio(child.stdin.take(), handle)?;
let stdout = stdio(child.stdout.take(), handle)?;
let stderr = stdio(child.stderr.take(), handle)?;
let stdin = stdio(child.stdin.take());
let stdout = stdio(child.stdout.take());
let stderr = stdio(child.stderr.take());
Ok(SpawnedChild {
child: Child {
@@ -182,15 +181,14 @@ pub(crate) type ChildStdin = PollEvented<NamedPipe>;
pub(crate) type ChildStdout = PollEvented<NamedPipe>;
pub(crate) type ChildStderr = PollEvented<NamedPipe>;
fn stdio<T>(option: Option<T>, handle: &Handle) -> io::Result<Option<PollEvented<NamedPipe>>>
fn stdio<T>(option: Option<T>) -> Option<PollEvented<NamedPipe>>
where
T: IntoRawHandle,
{
let io = match option {
Some(io) => io,
None => return Ok(None),
None => return None,
};
let pipe = unsafe { NamedPipe::from_raw_handle(io.into_raw_handle()) };
let io = PollEvented::new_with_handle(pipe, handle)?;
Ok(Some(io))
Some(PollEvented::new(pipe))
}