From a19374508c3aa612bfe53f09bb7b50fc2767ad14 Mon Sep 17 00:00:00 2001 From: Jiahao XU Date: Sun, 30 Jul 2023 22:26:24 +1000 Subject: [PATCH 1/3] Impl `{ChildStd*}::into_owned_{fd, handle}` Fixed #4403 and fixed #5333 Signed-off-by: Jiahao XU --- tokio/src/doc/os.rs | 3 + tokio/src/process/mod.rs | 121 ++++++++++++++++------------------ tokio/src/process/unix/mod.rs | 16 ++++- tokio/src/process/windows.rs | 18 +++-- 4 files changed, 85 insertions(+), 73 deletions(-) diff --git a/tokio/src/doc/os.rs b/tokio/src/doc/os.rs index 9404d4491f2..cded8b97cc0 100644 --- a/tokio/src/doc/os.rs +++ b/tokio/src/doc/os.rs @@ -11,6 +11,9 @@ pub mod windows { /// See [std::os::windows::io::RawHandle](https://doc.rust-lang.org/std/os/windows/io/type.RawHandle.html) pub type RawHandle = crate::doc::NotDefinedHere; + /// See [std::os::windows::io::OwnedHandle](https://doc.rust-lang.org/std/os/windows/io/struct.OwnedHandle.html) + pub type OwnedHandle = crate::doc::NotDefinedHere; + /// See [std::os::windows::io::AsRawHandle](https://doc.rust-lang.org/std/os/windows/io/trait.AsRawHandle.html) pub trait AsRawHandle { /// See [std::os::windows::io::AsRawHandle::as_raw_handle](https://doc.rust-lang.org/std/os/windows/io/trait.AsRawHandle.html#tymethod.as_raw_handle) diff --git a/tokio/src/process/mod.rs b/tokio/src/process/mod.rs index 5ab5647c29b..f8f67408820 100644 --- a/tokio/src/process/mod.rs +++ b/tokio/src/process/mod.rs @@ -259,7 +259,7 @@ use std::os::unix::process::CommandExt; use std::os::windows::process::CommandExt; cfg_windows! { - use crate::os::windows::io::{AsRawHandle, RawHandle, AsHandle, BorrowedHandle}; + use crate::os::windows::io::{AsRawHandle, RawHandle}; } /// This structure mimics the API of [`std::process::Command`] found in the standard library, but @@ -1447,84 +1447,75 @@ impl TryInto for ChildStderr { } #[cfg(unix)] +#[cfg_attr(docsrs, doc(cfg(unix)))] mod sys { - use std::os::unix::io::{AsFd, AsRawFd, BorrowedFd, RawFd}; + use std::{ + io, + os::unix::io::{AsFd, AsRawFd, BorrowedFd, OwnedFd, RawFd}, + }; use super::{ChildStderr, ChildStdin, ChildStdout}; - impl AsRawFd for ChildStdin { - fn as_raw_fd(&self) -> RawFd { - self.inner.as_raw_fd() - } - } - - impl AsFd for ChildStdin { - fn as_fd(&self) -> BorrowedFd<'_> { - unsafe { BorrowedFd::borrow_raw(self.as_raw_fd()) } - } - } - - impl AsRawFd for ChildStdout { - fn as_raw_fd(&self) -> RawFd { - self.inner.as_raw_fd() - } - } + macro_rules! impl_traits { + ($type:ty) => { + impl $type { + /// Convert into [`OwnedFd`]. + pub fn into_owned_fd(self) -> io::Result { + self.inner.into_owned_fd() + } + } - impl AsFd for ChildStdout { - fn as_fd(&self) -> BorrowedFd<'_> { - unsafe { BorrowedFd::borrow_raw(self.as_raw_fd()) } - } - } + impl AsRawFd for $type { + fn as_raw_fd(&self) -> RawFd { + self.inner.as_raw_fd() + } + } - impl AsRawFd for ChildStderr { - fn as_raw_fd(&self) -> RawFd { - self.inner.as_raw_fd() - } + impl AsFd for $type { + fn as_fd(&self) -> BorrowedFd<'_> { + unsafe { BorrowedFd::borrow_raw(self.as_raw_fd()) } + } + } + }; } - impl AsFd for ChildStderr { - fn as_fd(&self) -> BorrowedFd<'_> { - unsafe { BorrowedFd::borrow_raw(self.as_raw_fd()) } - } - } + impl_traits!(ChildStdin); + impl_traits!(ChildStdout); + impl_traits!(ChildStderr); } -cfg_windows! { - impl AsRawHandle for ChildStdin { - fn as_raw_handle(&self) -> RawHandle { - self.inner.as_raw_handle() - } - } - - impl AsHandle for ChildStdin { - fn as_handle(&self) -> BorrowedHandle<'_> { - unsafe { BorrowedHandle::borrow_raw(self.as_raw_handle()) } - } - } - - impl AsRawHandle for ChildStdout { - fn as_raw_handle(&self) -> RawHandle { - self.inner.as_raw_handle() - } - } +#[cfg(windows)] +#[cfg_attr(docsrs, doc(cfg(windows)))] +mod windows { + use super::*; + use crate::os::windows::io::{AsHandle, BorrowedHandle, OwnedHandle}; + + macro_rules! impl_traits { + ($type:ty) => { + impl $type { + /// Convert into [`OwnedHandle`]. + pub fn into_owned_handle(self) -> io::Result { + self.inner.into_owned_handle() + } + } - impl AsHandle for ChildStdout { - fn as_handle(&self) -> BorrowedHandle<'_> { - unsafe { BorrowedHandle::borrow_raw(self.as_raw_handle()) } - } - } + impl AsRawHandle for $type { + fn as_raw_handle(&self) -> RawHandle { + self.inner.as_raw_handle() + } + } - impl AsRawHandle for ChildStderr { - fn as_raw_handle(&self) -> RawHandle { - self.inner.as_raw_handle() - } + impl AsHandle for $type { + fn as_handle(&self) -> BorrowedHandle<'_> { + unsafe { BorrowedHandle::borrow_raw(self.as_raw_handle()) } + } + } + }; } - impl AsHandle for ChildStderr { - fn as_handle(&self) -> BorrowedHandle<'_> { - unsafe { BorrowedHandle::borrow_raw(self.as_raw_handle()) } - } - } + impl_traits!(ChildStdin); + impl_traits!(ChildStdout); + impl_traits!(ChildStderr); } #[cfg(all(test, not(loom)))] diff --git a/tokio/src/process/unix/mod.rs b/tokio/src/process/unix/mod.rs index 36991bf971f..b9c2d78e80d 100644 --- a/tokio/src/process/unix/mod.rs +++ b/tokio/src/process/unix/mod.rs @@ -39,7 +39,7 @@ use std::fmt; use std::fs::File; use std::future::Future; use std::io; -use std::os::unix::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, RawFd}; +use std::os::unix::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, OwnedFd, RawFd}; use std::pin::Pin; use std::process::{Child as StdChild, ExitStatus, Stdio}; use std::task::Context; @@ -200,7 +200,7 @@ impl AsFd for Pipe { } } -pub(crate) fn convert_to_stdio(io: ChildStdio) -> io::Result { +fn convert_to_blocking_file(io: ChildStdio) -> io::Result { let mut fd = io.inner.into_inner()?.fd; // Ensure that the fd to be inherited is set to *blocking* mode, as this @@ -209,7 +209,11 @@ pub(crate) fn convert_to_stdio(io: ChildStdio) -> io::Result { // change it to nonblocking mode. set_nonblocking(&mut fd, false)?; - Ok(Stdio::from(fd)) + Ok(fd) +} + +pub(crate) fn convert_to_stdio(io: ChildStdio) -> io::Result { + convert_to_blocking_file(io).map(Stdio::from) } impl Source for Pipe { @@ -240,6 +244,12 @@ pub(crate) struct ChildStdio { inner: PollEvented, } +impl ChildStdio { + pub(super) fn into_owned_fd(self) -> io::Result { + convert_to_blocking_file(self).map(OwnedFd::from) + } +} + impl fmt::Debug for ChildStdio { fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { self.inner.fmt(fmt) diff --git a/tokio/src/process/windows.rs b/tokio/src/process/windows.rs index eb412cdc55f..792a9c9610b 100644 --- a/tokio/src/process/windows.rs +++ b/tokio/src/process/windows.rs @@ -24,7 +24,7 @@ use std::fmt; use std::fs::File as StdFile; use std::future::Future; use std::io; -use std::os::windows::prelude::{AsRawHandle, IntoRawHandle, RawHandle}; +use std::os::windows::prelude::{AsRawHandle, IntoRawHandle, OwnedHandle, RawHandle}; use std::pin::Pin; use std::process::Stdio; use std::process::{Child as StdChild, Command as StdCommand, ExitStatus}; @@ -195,6 +195,12 @@ pub(crate) struct ChildStdio { io: Blocking, } +impl ChildStdio { + pub(super) fn into_owned_handle(self) -> io::Result { + convert_to_file(self).map(OwnedHandle::from) + } +} + impl AsRawHandle for ChildStdio { fn as_raw_handle(&self) -> RawHandle { self.raw.as_raw_handle() @@ -240,13 +246,15 @@ where Ok(ChildStdio { raw, io }) } -pub(crate) fn convert_to_stdio(child_stdio: ChildStdio) -> io::Result { +fn convert_to_file(child_stdio: ChildStdio) -> io::Result { let ChildStdio { raw, io } = child_stdio; drop(io); // Try to drop the Arc count here - Arc::try_unwrap(raw) - .or_else(|raw| duplicate_handle(&*raw)) - .map(Stdio::from) + Arc::try_unwrap(raw).or_else(|raw| duplicate_handle(&*raw)) +} + +pub(crate) fn convert_to_stdio(child_stdio: ChildStdio) -> io::Result { + convert_to_file(child_stdio).map(Stdio::from) } fn duplicate_handle(io: &T) -> io::Result { From f35bcd20b3701daffcba449b5ff2c0a63e603940 Mon Sep 17 00:00:00 2001 From: Jiahao XU Date: Fri, 4 Aug 2023 21:36:25 +1000 Subject: [PATCH 2/3] Update tokio/src/process/mod.rs Co-authored-by: Alice Ryhl --- tokio/src/process/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tokio/src/process/mod.rs b/tokio/src/process/mod.rs index f8f67408820..dc7b145a9f4 100644 --- a/tokio/src/process/mod.rs +++ b/tokio/src/process/mod.rs @@ -1484,7 +1484,7 @@ mod sys { impl_traits!(ChildStderr); } -#[cfg(windows)] +#[cfg(any(windows, docsrs))] #[cfg_attr(docsrs, doc(cfg(windows)))] mod windows { use super::*; From 4137b6e8921ad35718a088581822c6d5131681a5 Mon Sep 17 00:00:00 2001 From: Jiahao XU Date: Fri, 4 Aug 2023 21:40:37 +1000 Subject: [PATCH 3/3] Fix doc compilation Signed-off-by: Jiahao XU --- tokio/src/process/mod.rs | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/tokio/src/process/mod.rs b/tokio/src/process/mod.rs index dc7b145a9f4..3672f117afd 100644 --- a/tokio/src/process/mod.rs +++ b/tokio/src/process/mod.rs @@ -1488,8 +1488,9 @@ mod sys { #[cfg_attr(docsrs, doc(cfg(windows)))] mod windows { use super::*; - use crate::os::windows::io::{AsHandle, BorrowedHandle, OwnedHandle}; + use crate::os::windows::io::{AsHandle, AsRawHandle, BorrowedHandle, OwnedHandle, RawHandle}; + #[cfg(not(docsrs))] macro_rules! impl_traits { ($type:ty) => { impl $type { @@ -1513,6 +1514,30 @@ mod windows { }; } + #[cfg(docsrs)] + macro_rules! impl_traits { + ($type:ty) => { + impl $type { + /// Convert into [`OwnedHandle`]. + pub fn into_owned_handle(self) -> io::Result { + todo!("For doc generation only") + } + } + + impl AsRawHandle for $type { + fn as_raw_handle(&self) -> RawHandle { + todo!("For doc generation only") + } + } + + impl AsHandle for $type { + fn as_handle(&self) -> BorrowedHandle<'_> { + todo!("For doc generation only") + } + } + }; + } + impl_traits!(ChildStdin); impl_traits!(ChildStdout); impl_traits!(ChildStderr);