From 9cc1689de451f7723eedd7831665a38081eb61b5 Mon Sep 17 00:00:00 2001 From: Alice Ryhl Date: Tue, 17 Aug 2021 14:49:32 +0000 Subject: [PATCH 1/2] process: add from_std to ChildStd* --- tokio/src/process/mod.rs | 57 +++++++++++++++++++++++++++++++---- tokio/src/process/unix/mod.rs | 19 ++++-------- tokio/src/process/windows.rs | 18 ++++------- 3 files changed, 63 insertions(+), 31 deletions(-) diff --git a/tokio/src/process/mod.rs b/tokio/src/process/mod.rs index 42654b19830..7a150242a67 100644 --- a/tokio/src/process/mod.rs +++ b/tokio/src/process/mod.rs @@ -225,9 +225,9 @@ pub struct Command { pub(crate) struct SpawnedChild { child: imp::Child, - stdin: Option, - stdout: Option, - stderr: Option, + stdin: Option, + stdout: Option, + stderr: Option, } 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 { + 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 { + 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 { + Ok(Self { + inner: imp::stdio(inner)?, + }) + } } impl AsyncWrite for ChildStdin { diff --git a/tokio/src/process/unix/mod.rs b/tokio/src/process/unix/mod.rs index fab63dd3d5f..f3dbf30345b 100644 --- a/tokio/src/process/unix/mod.rs +++ b/tokio/src/process/unix/mod.rs @@ -101,9 +101,9 @@ impl fmt::Debug for Child { pub(crate) fn spawn_child(cmd: &mut std::process::Command) -> io::Result { 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; -pub(crate) type ChildStdout = PollEvented; -pub(crate) type ChildStderr = PollEvented; +pub(crate) type ChildStdio = PollEvented; fn set_nonblocking(fd: &mut T, nonblocking: bool) -> io::Result<()> { unsafe { @@ -240,18 +238,13 @@ fn set_nonblocking(fd: &mut T, nonblocking: bool) -> io::Result<()> Ok(()) } -fn stdio(option: Option) -> io::Result>> +pub(super) fn stdio(io: T) -> io::Result> 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)?)) + Ok(PollEvented::new(pipe)?) } diff --git a/tokio/src/process/windows.rs b/tokio/src/process/windows.rs index 06fc1b6cf80..13fe6a1c0ff 100644 --- a/tokio/src/process/windows.rs +++ b/tokio/src/process/windows.rs @@ -67,9 +67,9 @@ unsafe impl Send for Waiting {} pub(crate) fn spawn_child(cmd: &mut StdCommand) -> io::Result { 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; -pub(crate) type ChildStdout = PollEvented; -pub(crate) type ChildStderr = PollEvented; +pub(crate) type ChildStdio = PollEvented; -fn stdio(option: Option) -> Option> +pub(super) fn stdio(option: T) -> io::Result> 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) -> io::Result { From 928d0c44fb3579db318c109c1dfaca5d777ba185 Mon Sep 17 00:00:00 2001 From: Alice Ryhl Date: Tue, 17 Aug 2021 14:58:40 +0000 Subject: [PATCH 2/2] Fix CI failures --- tokio/src/process/unix/mod.rs | 2 +- tokio/src/process/windows.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tokio/src/process/unix/mod.rs b/tokio/src/process/unix/mod.rs index f3dbf30345b..0f379c9fcd6 100644 --- a/tokio/src/process/unix/mod.rs +++ b/tokio/src/process/unix/mod.rs @@ -246,5 +246,5 @@ where let mut pipe = Pipe::from(io); set_nonblocking(&mut pipe, true)?; - Ok(PollEvented::new(pipe)?) + PollEvented::new(pipe) } diff --git a/tokio/src/process/windows.rs b/tokio/src/process/windows.rs index 13fe6a1c0ff..136d5b0cab8 100644 --- a/tokio/src/process/windows.rs +++ b/tokio/src/process/windows.rs @@ -169,7 +169,7 @@ unsafe extern "system" fn callback(ptr: PVOID, _timer_fired: BOOLEAN) { pub(crate) type ChildStdio = PollEvented; -pub(super) fn stdio(option: T) -> io::Result> +pub(super) fn stdio(io: T) -> io::Result> where T: IntoRawHandle, {