mirror of
https://github.com/tokio-rs/tokio.git
synced 2026-08-29 00:00:11 +02:00
process: add {ChildStd*}::into_owned_{fd, handle} (#5899)
This commit is contained in:
@@ -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)
|
||||
|
||||
+83
-67
@@ -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,100 @@ impl TryInto<Stdio> 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()
|
||||
}
|
||||
macro_rules! impl_traits {
|
||||
($type:ty) => {
|
||||
impl $type {
|
||||
/// Convert into [`OwnedFd`].
|
||||
pub fn into_owned_fd(self) -> io::Result<OwnedFd> {
|
||||
self.inner.into_owned_fd()
|
||||
}
|
||||
}
|
||||
|
||||
impl AsRawFd for $type {
|
||||
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 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()
|
||||
}
|
||||
}
|
||||
|
||||
impl AsFd for ChildStdout {
|
||||
fn as_fd(&self) -> BorrowedFd<'_> {
|
||||
unsafe { BorrowedFd::borrow_raw(self.as_raw_fd()) }
|
||||
}
|
||||
}
|
||||
|
||||
impl AsRawFd for ChildStderr {
|
||||
fn as_raw_fd(&self) -> RawFd {
|
||||
self.inner.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()
|
||||
}
|
||||
#[cfg(any(windows, docsrs))]
|
||||
#[cfg_attr(docsrs, doc(cfg(windows)))]
|
||||
mod windows {
|
||||
use super::*;
|
||||
use crate::os::windows::io::{AsHandle, AsRawHandle, BorrowedHandle, OwnedHandle, RawHandle};
|
||||
|
||||
#[cfg(not(docsrs))]
|
||||
macro_rules! impl_traits {
|
||||
($type:ty) => {
|
||||
impl $type {
|
||||
/// Convert into [`OwnedHandle`].
|
||||
pub fn into_owned_handle(self) -> io::Result<OwnedHandle> {
|
||||
self.inner.into_owned_handle()
|
||||
}
|
||||
}
|
||||
|
||||
impl AsRawHandle for $type {
|
||||
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 ChildStdin {
|
||||
fn as_handle(&self) -> BorrowedHandle<'_> {
|
||||
unsafe { BorrowedHandle::borrow_raw(self.as_raw_handle()) }
|
||||
}
|
||||
#[cfg(docsrs)]
|
||||
macro_rules! impl_traits {
|
||||
($type:ty) => {
|
||||
impl $type {
|
||||
/// Convert into [`OwnedHandle`].
|
||||
pub fn into_owned_handle(self) -> io::Result<OwnedHandle> {
|
||||
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 AsRawHandle for ChildStdout {
|
||||
fn as_raw_handle(&self) -> RawHandle {
|
||||
self.inner.as_raw_handle()
|
||||
}
|
||||
}
|
||||
|
||||
impl AsHandle for ChildStdout {
|
||||
fn as_handle(&self) -> BorrowedHandle<'_> {
|
||||
unsafe { BorrowedHandle::borrow_raw(self.as_raw_handle()) }
|
||||
}
|
||||
}
|
||||
|
||||
impl AsRawHandle for ChildStderr {
|
||||
fn as_raw_handle(&self) -> RawHandle {
|
||||
self.inner.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)))]
|
||||
|
||||
@@ -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<Stdio> {
|
||||
fn convert_to_blocking_file(io: ChildStdio) -> io::Result<File> {
|
||||
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<Stdio> {
|
||||
// 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<Stdio> {
|
||||
convert_to_blocking_file(io).map(Stdio::from)
|
||||
}
|
||||
|
||||
impl Source for Pipe {
|
||||
@@ -240,6 +244,12 @@ pub(crate) struct ChildStdio {
|
||||
inner: PollEvented<Pipe>,
|
||||
}
|
||||
|
||||
impl ChildStdio {
|
||||
pub(super) fn into_owned_fd(self) -> io::Result<OwnedFd> {
|
||||
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)
|
||||
|
||||
@@ -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<ArcFile>,
|
||||
}
|
||||
|
||||
impl ChildStdio {
|
||||
pub(super) fn into_owned_handle(self) -> io::Result<OwnedHandle> {
|
||||
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<Stdio> {
|
||||
fn convert_to_file(child_stdio: ChildStdio) -> io::Result<StdFile> {
|
||||
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<Stdio> {
|
||||
convert_to_file(child_stdio).map(Stdio::from)
|
||||
}
|
||||
|
||||
fn duplicate_handle<T: AsRawHandle>(io: &T) -> io::Result<StdFile> {
|
||||
|
||||
Reference in New Issue
Block a user