Skip to content

Commit bf150ff

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 bf150ff

File tree

3 files changed

+76
-72
lines changed

3 files changed

+76
-72
lines changed

tokio/src/process/mod.rs

+50-64
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, AsHandle, BorrowedHandle, OwnedHandle};
263263
}
264264

265265
/// This structure mimics the API of [`std::process::Command`] found in the standard library, but
@@ -1447,84 +1447,70 @@ 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

14921487
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-
}
1488+
macro_rules! impl_traits {
1489+
($type:ty) => {
1490+
impl $type {
1491+
/// Convert into [`OwnedHandle`].
1492+
pub fn into_owned_handle(self) -> io::Result<OwnedHandle> {
1493+
self.inner.into_owned_handle()
1494+
}
1495+
}
15101496

1511-
impl AsHandle for ChildStdout {
1512-
fn as_handle(&self) -> BorrowedHandle<'_> {
1513-
unsafe { BorrowedHandle::borrow_raw(self.as_raw_handle()) }
1514-
}
1515-
}
1497+
impl AsRawHandle for $type {
1498+
fn as_raw_handle(&self) -> RawHandle {
1499+
self.inner.as_raw_handle()
1500+
}
1501+
}
15161502

1517-
impl AsRawHandle for ChildStderr {
1518-
fn as_raw_handle(&self) -> RawHandle {
1519-
self.inner.as_raw_handle()
1520-
}
1503+
impl AsHandle for $type {
1504+
fn as_handle(&self) -> BorrowedHandle<'_> {
1505+
unsafe { BorrowedHandle::borrow_raw(self.as_raw_handle()) }
1506+
}
1507+
}
1508+
};
15211509
}
15221510

1523-
impl AsHandle for ChildStderr {
1524-
fn as_handle(&self) -> BorrowedHandle<'_> {
1525-
unsafe { BorrowedHandle::borrow_raw(self.as_raw_handle()) }
1526-
}
1527-
}
1511+
impl_traits!(ChildStdin);
1512+
impl_traits!(ChildStdout);
1513+
impl_traits!(ChildStderr);
15281514
}
15291515

15301516
#[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)