Skip to content

Commit 35cb474

Browse files
committed
Impl {ChildStd*}::into_owned_{fd, handle}
Fixed #4403 and fixed #5333 Signed-off-by: Jiahao XU <[email protected]>
1 parent efe3ab6 commit 35cb474

File tree

4 files changed

+85
-73
lines changed

4 files changed

+85
-73
lines changed

tokio/src/doc/os.rs

+3
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@ pub mod windows {
1111
/// See [std::os::windows::io::RawHandle](https://doc.rust-lang.org/std/os/windows/io/type.RawHandle.html)
1212
pub type RawHandle = crate::doc::NotDefinedHere;
1313

14+
/// See [std::os::windows::io::OwnedHandle](https://doc.rust-lang.org/std/os/windows/io/struct.OwnedHandle.html)
15+
pub type OwnedHandle = crate::doc::NotDefinedHere;
16+
1417
/// See [std::os::windows::io::AsRawHandle](https://doc.rust-lang.org/std/os/windows/io/trait.AsRawHandle.html)
1518
pub trait AsRawHandle {
1619
/// 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)

tokio/src/process/mod.rs

+56-65
Original file line numberDiff line numberDiff line change
@@ -259,7 +259,7 @@ use std::os::unix::process::CommandExt;
259259
use std::os::windows::process::CommandExt;
260260

261261
cfg_windows! {
262-
use crate::os::windows::io::{AsRawHandle, RawHandle, AsHandle, BorrowedHandle};
262+
use crate::os::windows::io::{AsRawHandle, RawHandle};
263263
}
264264

265265
/// This structure mimics the API of [`std::process::Command`] found in the standard library, but
@@ -1447,84 +1447,75 @@ impl TryInto<Stdio> for ChildStderr {
14471447
}
14481448

14491449
#[cfg(unix)]
1450+
#[cfg_attr(docsrs, doc(cfg(unix)))]
14501451
mod sys {
1451-
use std::os::unix::io::{AsFd, AsRawFd, BorrowedFd, RawFd};
1452+
use std::{
1453+
io,
1454+
os::unix::io::{AsFd, AsRawFd, BorrowedFd, OwnedFd, RawFd},
1455+
};
14521456

14531457
use super::{ChildStderr, ChildStdin, ChildStdout};
14541458

1455-
impl AsRawFd for ChildStdin {
1456-
fn as_raw_fd(&self) -> RawFd {
1457-
self.inner.as_raw_fd()
1458-
}
1459-
}
1460-
1461-
impl AsFd for ChildStdin {
1462-
fn as_fd(&self) -> BorrowedFd<'_> {
1463-
unsafe { BorrowedFd::borrow_raw(self.as_raw_fd()) }
1464-
}
1465-
}
1466-
1467-
impl AsRawFd for ChildStdout {
1468-
fn as_raw_fd(&self) -> RawFd {
1469-
self.inner.as_raw_fd()
1470-
}
1471-
}
1459+
macro_rules! impl_traits {
1460+
($type:ty) => {
1461+
impl $type {
1462+
/// Convert into [`OwnedFd`].
1463+
pub fn into_owned_fd(self) -> io::Result<OwnedFd> {
1464+
self.inner.into_owned_fd()
1465+
}
1466+
}
14721467

1473-
impl AsFd for ChildStdout {
1474-
fn as_fd(&self) -> BorrowedFd<'_> {
1475-
unsafe { BorrowedFd::borrow_raw(self.as_raw_fd()) }
1476-
}
1477-
}
1468+
impl AsRawFd for $type {
1469+
fn as_raw_fd(&self) -> RawFd {
1470+
self.inner.as_raw_fd()
1471+
}
1472+
}
14781473

1479-
impl AsRawFd for ChildStderr {
1480-
fn as_raw_fd(&self) -> RawFd {
1481-
self.inner.as_raw_fd()
1482-
}
1474+
impl AsFd for $type {
1475+
fn as_fd(&self) -> BorrowedFd<'_> {
1476+
unsafe { BorrowedFd::borrow_raw(self.as_raw_fd()) }
1477+
}
1478+
}
1479+
};
14831480
}
14841481

1485-
impl AsFd for ChildStderr {
1486-
fn as_fd(&self) -> BorrowedFd<'_> {
1487-
unsafe { BorrowedFd::borrow_raw(self.as_raw_fd()) }
1488-
}
1489-
}
1482+
impl_traits!(ChildStdin);
1483+
impl_traits!(ChildStdout);
1484+
impl_traits!(ChildStderr);
14901485
}
14911486

1492-
cfg_windows! {
1493-
impl AsRawHandle for ChildStdin {
1494-
fn as_raw_handle(&self) -> RawHandle {
1495-
self.inner.as_raw_handle()
1496-
}
1497-
}
1498-
1499-
impl AsHandle for ChildStdin {
1500-
fn as_handle(&self) -> BorrowedHandle<'_> {
1501-
unsafe { BorrowedHandle::borrow_raw(self.as_raw_handle()) }
1502-
}
1503-
}
1504-
1505-
impl AsRawHandle for ChildStdout {
1506-
fn as_raw_handle(&self) -> RawHandle {
1507-
self.inner.as_raw_handle()
1508-
}
1509-
}
1487+
#[cfg(windows)]
1488+
#[cfg_attr(docsrs, doc(cfg(windows)))]
1489+
mod windows {
1490+
use super::*;
1491+
use crate::os::windows::io::{AsHandle, BorrowedHandle, OwnedHandle};
1492+
1493+
macro_rules! impl_traits {
1494+
($type:ty) => {
1495+
impl $type {
1496+
/// Convert into [`OwnedHandle`].
1497+
pub fn into_owned_handle(self) -> io::Result<OwnedHandle> {
1498+
self.inner.into_owned_handle()
1499+
}
1500+
}
15101501

1511-
impl AsHandle for ChildStdout {
1512-
fn as_handle(&self) -> BorrowedHandle<'_> {
1513-
unsafe { BorrowedHandle::borrow_raw(self.as_raw_handle()) }
1514-
}
1515-
}
1502+
impl AsRawHandle for $type {
1503+
fn as_raw_handle(&self) -> RawHandle {
1504+
self.inner.as_raw_handle()
1505+
}
1506+
}
15161507

1517-
impl AsRawHandle for ChildStderr {
1518-
fn as_raw_handle(&self) -> RawHandle {
1519-
self.inner.as_raw_handle()
1520-
}
1508+
impl AsHandle for $type {
1509+
fn as_handle(&self) -> BorrowedHandle<'_> {
1510+
unsafe { BorrowedHandle::borrow_raw(self.as_raw_handle()) }
1511+
}
1512+
}
1513+
};
15211514
}
15221515

1523-
impl AsHandle for ChildStderr {
1524-
fn as_handle(&self) -> BorrowedHandle<'_> {
1525-
unsafe { BorrowedHandle::borrow_raw(self.as_raw_handle()) }
1526-
}
1527-
}
1516+
impl_traits!(ChildStdin);
1517+
impl_traits!(ChildStdout);
1518+
impl_traits!(ChildStderr);
15281519
}
15291520

15301521
#[cfg(all(test, not(loom)))]

tokio/src/process/unix/mod.rs

+13-3
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ use std::fmt;
3939
use std::fs::File;
4040
use std::future::Future;
4141
use std::io;
42-
use std::os::unix::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, RawFd};
42+
use std::os::unix::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, OwnedFd, RawFd};
4343
use std::pin::Pin;
4444
use std::process::{Child as StdChild, ExitStatus, Stdio};
4545
use std::task::Context;
@@ -200,7 +200,7 @@ impl AsFd for Pipe {
200200
}
201201
}
202202

203-
pub(crate) fn convert_to_stdio(io: ChildStdio) -> io::Result<Stdio> {
203+
fn convert_to_blocking_file(io: ChildStdio) -> io::Result<File> {
204204
let mut fd = io.inner.into_inner()?.fd;
205205

206206
// 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> {
209209
// change it to nonblocking mode.
210210
set_nonblocking(&mut fd, false)?;
211211

212-
Ok(Stdio::from(fd))
212+
Ok(fd)
213+
}
214+
215+
pub(crate) fn convert_to_stdio(io: ChildStdio) -> io::Result<Stdio> {
216+
convert_to_blocking_file(io).map(Stdio::from)
213217
}
214218

215219
impl Source for Pipe {
@@ -240,6 +244,12 @@ pub(crate) struct ChildStdio {
240244
inner: PollEvented<Pipe>,
241245
}
242246

247+
impl ChildStdio {
248+
pub(super) fn into_owned_fd(self) -> io::Result<OwnedFd> {
249+
convert_to_blocking_file(self).map(OwnedFd::from)
250+
}
251+
}
252+
243253
impl fmt::Debug for ChildStdio {
244254
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
245255
self.inner.fmt(fmt)

tokio/src/process/windows.rs

+13-5
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ use std::fmt;
2424
use std::fs::File as StdFile;
2525
use std::future::Future;
2626
use std::io;
27-
use std::os::windows::prelude::{AsRawHandle, IntoRawHandle, RawHandle};
27+
use std::os::windows::prelude::{AsRawHandle, IntoRawHandle, OwnedHandle, RawHandle};
2828
use std::pin::Pin;
2929
use std::process::Stdio;
3030
use std::process::{Child as StdChild, Command as StdCommand, ExitStatus};
@@ -195,6 +195,12 @@ pub(crate) struct ChildStdio {
195195
io: Blocking<ArcFile>,
196196
}
197197

198+
impl ChildStdio {
199+
pub(super) fn into_owned_handle(self) -> io::Result<OwnedHandle> {
200+
convert_to_file(self).map(OwnedHandle::from)
201+
}
202+
}
203+
198204
impl AsRawHandle for ChildStdio {
199205
fn as_raw_handle(&self) -> RawHandle {
200206
self.raw.as_raw_handle()
@@ -240,13 +246,15 @@ where
240246
Ok(ChildStdio { raw, io })
241247
}
242248

243-
pub(crate) fn convert_to_stdio(child_stdio: ChildStdio) -> io::Result<Stdio> {
249+
fn convert_to_file(child_stdio: ChildStdio) -> io::Result<StdFile> {
244250
let ChildStdio { raw, io } = child_stdio;
245251
drop(io); // Try to drop the Arc count here
246252

247-
Arc::try_unwrap(raw)
248-
.or_else(|raw| duplicate_handle(&*raw))
249-
.map(Stdio::from)
253+
Arc::try_unwrap(raw).or_else(|raw| duplicate_handle(&*raw))
254+
}
255+
256+
pub(crate) fn convert_to_stdio(child_stdio: ChildStdio) -> io::Result<Stdio> {
257+
convert_to_file(child_stdio).map(Stdio::from)
250258
}
251259

252260
fn duplicate_handle<T: AsRawHandle>(io: &T) -> io::Result<StdFile> {

0 commit comments

Comments
 (0)