process: add from_std to ChildStd* (#4045)

This commit is contained in:
Alice Ryhl
2021-08-19 09:46:05 +02:00
committed by GitHub
parent 8aa2bfe23e
commit 2bc9a42d2b
3 changed files with 63 additions and 31 deletions
+51 -6
View File
@@ -225,9 +225,9 @@ pub struct Command {
pub(crate) struct SpawnedChild {
child: imp::Child,
stdin: Option<imp::ChildStdin>,
stdout: Option<imp::ChildStdout>,
stderr: Option<imp::ChildStderr>,
stdin: Option<imp::ChildStdio>,
stdout: Option<imp::ChildStdio>,
stderr: Option<imp::ChildStdio>,
}
impl Command {
@@ -1151,7 +1151,7 @@ impl Child {
/// handle of a child process asynchronously.
#[derive(Debug)]
pub struct ChildStdin {
inner: imp::ChildStdin,
inner: imp::ChildStdio,
}
/// The standard output stream for spawned children.
@@ -1160,7 +1160,7 @@ pub struct ChildStdin {
/// handle of a child process asynchronously.
#[derive(Debug)]
pub struct ChildStdout {
inner: imp::ChildStdout,
inner: imp::ChildStdio,
}
/// The standard error stream for spawned children.
@@ -1169,7 +1169,52 @@ pub struct ChildStdout {
/// handle of a child process asynchronously.
#[derive(Debug)]
pub struct ChildStderr {
inner: imp::ChildStderr,
inner: imp::ChildStdio,
}
impl ChildStdin {
/// Create an asynchronous `ChildStdin` from a synchronous one.
///
/// # Errors
///
/// This method may fail if an error is encountered when setting the pipe to
/// non-blocking mode, or when registering the pipe with the runtime's IO
/// driver.
pub fn from_std(inner: std::process::ChildStdin) -> io::Result<Self> {
Ok(Self {
inner: imp::stdio(inner)?,
})
}
}
impl ChildStdout {
/// Create an asynchronous `ChildStderr` from a synchronous one.
///
/// # Errors
///
/// This method may fail if an error is encountered when setting the pipe to
/// non-blocking mode, or when registering the pipe with the runtime's IO
/// driver.
pub fn from_std(inner: std::process::ChildStdout) -> io::Result<Self> {
Ok(Self {
inner: imp::stdio(inner)?,
})
}
}
impl ChildStderr {
/// Create an asynchronous `ChildStderr` from a synchronous one.
///
/// # Errors
///
/// This method may fail if an error is encountered when setting the pipe to
/// non-blocking mode, or when registering the pipe with the runtime's IO
/// driver.
pub fn from_std(inner: std::process::ChildStderr) -> io::Result<Self> {
Ok(Self {
inner: imp::stdio(inner)?,
})
}
}
impl AsyncWrite for ChildStdin {
+6 -13
View File
@@ -101,9 +101,9 @@ impl fmt::Debug for Child {
pub(crate) fn spawn_child(cmd: &mut std::process::Command) -> io::Result<SpawnedChild> {
let mut child = cmd.spawn()?;
let stdin = stdio(child.stdin.take())?;
let stdout = stdio(child.stdout.take())?;
let stderr = stdio(child.stderr.take())?;
let stdin = child.stdin.take().map(stdio).transpose()?;
let stdout = child.stdout.take().map(stdio).transpose()?;
let stderr = child.stderr.take().map(stdio).transpose()?;
let signal = signal(SignalKind::child())?;
@@ -213,9 +213,7 @@ impl Source for Pipe {
}
}
pub(crate) type ChildStdin = PollEvented<Pipe>;
pub(crate) type ChildStdout = PollEvented<Pipe>;
pub(crate) type ChildStderr = PollEvented<Pipe>;
pub(crate) type ChildStdio = PollEvented<Pipe>;
fn set_nonblocking<T: AsRawFd>(fd: &mut T, nonblocking: bool) -> io::Result<()> {
unsafe {
@@ -240,18 +238,13 @@ fn set_nonblocking<T: AsRawFd>(fd: &mut T, nonblocking: bool) -> io::Result<()>
Ok(())
}
fn stdio<T>(option: Option<T>) -> io::Result<Option<PollEvented<Pipe>>>
pub(super) fn stdio<T>(io: T) -> io::Result<PollEvented<Pipe>>
where
T: IntoRawFd,
{
let io = match option {
Some(io) => io,
None => return Ok(None),
};
// Set the fd to nonblocking before we pass it to the event loop
let mut pipe = Pipe::from(io);
set_nonblocking(&mut pipe, true)?;
Ok(Some(PollEvented::new(pipe)?))
PollEvented::new(pipe)
}
+6 -12
View File
@@ -67,9 +67,9 @@ unsafe impl Send for Waiting {}
pub(crate) fn spawn_child(cmd: &mut StdCommand) -> io::Result<SpawnedChild> {
let mut child = cmd.spawn()?;
let stdin = stdio(child.stdin.take());
let stdout = stdio(child.stdout.take());
let stderr = stdio(child.stderr.take());
let stdin = child.stdin.take().map(stdio).transpose()?;
let stdout = child.stdout.take().map(stdio).transpose()?;
let stderr = child.stderr.take().map(stdio).transpose()?;
Ok(SpawnedChild {
child: Child {
@@ -167,20 +167,14 @@ unsafe extern "system" fn callback(ptr: PVOID, _timer_fired: BOOLEAN) {
let _ = complete.take().unwrap().send(());
}
pub(crate) type ChildStdin = PollEvented<NamedPipe>;
pub(crate) type ChildStdout = PollEvented<NamedPipe>;
pub(crate) type ChildStderr = PollEvented<NamedPipe>;
pub(crate) type ChildStdio = PollEvented<NamedPipe>;
fn stdio<T>(option: Option<T>) -> Option<PollEvented<NamedPipe>>
pub(super) fn stdio<T>(io: T) -> io::Result<PollEvented<NamedPipe>>
where
T: IntoRawHandle,
{
let io = match option {
Some(io) => io,
None => return None,
};
let pipe = unsafe { NamedPipe::from_raw_handle(io.into_raw_handle()) };
PollEvented::new(pipe).ok()
PollEvented::new(pipe)
}
pub(crate) fn convert_to_stdio(io: PollEvented<NamedPipe>) -> io::Result<Stdio> {