Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Stablize anonymous pipe #137793

Merged
merged 2 commits into from
Mar 17, 2025
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion library/std/src/io/mod.rs
Original file line number Diff line number Diff line change
@@ -310,7 +310,7 @@ pub use self::error::RawOsError;
pub use self::error::SimpleMessage;
#[unstable(feature = "io_const_error", issue = "133448")]
pub use self::error::const_error;
#[unstable(feature = "anonymous_pipe", issue = "127154")]
#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")]
pub use self::pipe::{PipeReader, PipeWriter, pipe};
#[stable(feature = "is_terminal", since = "1.70.0")]
pub use self::stdio::IsTerminal;
46 changes: 34 additions & 12 deletions library/std/src/io/pipe.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use crate::io;
use crate::sys::anonymous_pipe::{AnonPipe, pipe as pipe_inner};
use crate::sys_common::{FromInner, IntoInner};

/// Create an anonymous pipe.
///
@@ -40,7 +41,6 @@ use crate::sys::anonymous_pipe::{AnonPipe, pipe as pipe_inner};
/// # Examples
///
/// ```no_run
/// #![feature(anonymous_pipe)]
/// # #[cfg(miri)] fn main() {}
/// # #[cfg(not(miri))]
/// # fn main() -> std::io::Result<()> {
@@ -67,29 +67,52 @@ use crate::sys::anonymous_pipe::{AnonPipe, pipe as pipe_inner};
/// ```
/// [changes]: io#platform-specific-behavior
/// [man page]: https://man7.org/linux/man-pages/man7/pipe.7.html
#[unstable(feature = "anonymous_pipe", issue = "127154")]
#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")]
#[inline]
pub fn pipe() -> io::Result<(PipeReader, PipeWriter)> {
pipe_inner().map(|(reader, writer)| (PipeReader(reader), PipeWriter(writer)))
}

/// Read end of an anonymous pipe.
#[unstable(feature = "anonymous_pipe", issue = "127154")]
#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")]
#[derive(Debug)]
pub struct PipeReader(pub(crate) AnonPipe);

/// Write end of an anonymous pipe.
#[unstable(feature = "anonymous_pipe", issue = "127154")]
#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")]
#[derive(Debug)]
pub struct PipeWriter(pub(crate) AnonPipe);

impl FromInner<AnonPipe> for PipeReader {
fn from_inner(inner: AnonPipe) -> Self {
Self(inner)
}
}

impl IntoInner<AnonPipe> for PipeReader {
fn into_inner(self) -> AnonPipe {
self.0
}
}

impl FromInner<AnonPipe> for PipeWriter {
fn from_inner(inner: AnonPipe) -> Self {
Self(inner)
}
}

impl IntoInner<AnonPipe> for PipeWriter {
fn into_inner(self) -> AnonPipe {
self.0
}
}

impl PipeReader {
/// Create a new [`PipeReader`] instance that shares the same underlying file description.
///
/// # Examples
///
/// ```no_run
/// #![feature(anonymous_pipe)]
/// # #[cfg(miri)] fn main() {}
/// # #[cfg(not(miri))]
/// # fn main() -> std::io::Result<()> {
@@ -137,7 +160,7 @@ impl PipeReader {
/// # Ok(())
/// # }
/// ```
#[unstable(feature = "anonymous_pipe", issue = "127154")]
#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")]
pub fn try_clone(&self) -> io::Result<Self> {
self.0.try_clone().map(Self)
}
@@ -149,7 +172,6 @@ impl PipeWriter {
/// # Examples
///
/// ```no_run
/// #![feature(anonymous_pipe)]
/// # #[cfg(miri)] fn main() {}
/// # #[cfg(not(miri))]
/// # fn main() -> std::io::Result<()> {
@@ -177,13 +199,13 @@ impl PipeWriter {
/// # Ok(())
/// # }
/// ```
#[unstable(feature = "anonymous_pipe", issue = "127154")]
#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")]
pub fn try_clone(&self) -> io::Result<Self> {
self.0.try_clone().map(Self)
}
}

#[unstable(feature = "anonymous_pipe", issue = "127154")]
#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")]
impl io::Read for &PipeReader {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
self.0.read(buf)
@@ -203,7 +225,7 @@ impl io::Read for &PipeReader {
}
}

#[unstable(feature = "anonymous_pipe", issue = "127154")]
#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")]
impl io::Read for PipeReader {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
self.0.read(buf)
@@ -223,7 +245,7 @@ impl io::Read for PipeReader {
}
}

#[unstable(feature = "anonymous_pipe", issue = "127154")]
#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")]
impl io::Write for &PipeWriter {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
self.0.write(buf)
@@ -241,7 +263,7 @@ impl io::Write for &PipeWriter {
}
}

#[unstable(feature = "anonymous_pipe", issue = "127154")]
#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")]
impl io::Write for PipeWriter {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
self.0.write(buf)
45 changes: 44 additions & 1 deletion library/std/src/os/fd/owned.rs
Original file line number Diff line number Diff line change
@@ -15,8 +15,9 @@ use crate::mem::ManuallyDrop;
target_os = "trusty"
)))]
use crate::sys::cvt;
use crate::sys_common::FromInner;
#[cfg(not(target_os = "trusty"))]
use crate::sys_common::{AsInner, FromInner, IntoInner};
use crate::sys_common::{AsInner, IntoInner};
use crate::{fmt, io};

type ValidRawFd = core::num::niche_types::NotAllOnes<RawFd>;
@@ -504,3 +505,45 @@ impl<'a> AsFd for io::StderrLock<'a> {
unsafe { BorrowedFd::borrow_raw(2) }
}
}

#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")]
impl AsFd for io::PipeReader {
fn as_fd(&self) -> BorrowedFd<'_> {
self.0.as_fd()
}
}

#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")]
impl From<io::PipeReader> for OwnedFd {
fn from(pipe: io::PipeReader) -> Self {
pipe.0.into_inner()
}
}

#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")]
impl AsFd for io::PipeWriter {
fn as_fd(&self) -> BorrowedFd<'_> {
self.0.as_fd()
}
}

#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")]
impl From<io::PipeWriter> for OwnedFd {
fn from(pipe: io::PipeWriter) -> Self {
pipe.0.into_inner()
}
}

#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")]
impl From<OwnedFd> for io::PipeReader {
fn from(owned_fd: OwnedFd) -> Self {
Self(FromInner::from_inner(owned_fd))
}
}

#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")]
impl From<OwnedFd> for io::PipeWriter {
fn from(owned_fd: OwnedFd) -> Self {
Self(FromInner::from_inner(owned_fd))
}
}
43 changes: 43 additions & 0 deletions library/std/src/os/fd/raw.rs
Original file line number Diff line number Diff line change
@@ -18,6 +18,7 @@ use crate::os::unix::io::AsFd;
use crate::os::unix::io::OwnedFd;
#[cfg(target_os = "wasi")]
use crate::os::wasi::io::OwnedFd;
use crate::sys_common::FromInner;
#[cfg(not(target_os = "trusty"))]
use crate::sys_common::{AsInner, IntoInner};

@@ -284,3 +285,45 @@ impl<T: AsRawFd> AsRawFd for Box<T> {
(**self).as_raw_fd()
}
}

#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")]
impl AsRawFd for io::PipeReader {
fn as_raw_fd(&self) -> RawFd {
self.0.as_raw_fd()
}
}

#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")]
impl FromRawFd for io::PipeReader {
unsafe fn from_raw_fd(raw_fd: RawFd) -> Self {
Self::from_inner(unsafe { FromRawFd::from_raw_fd(raw_fd) })
}
}

#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")]
impl IntoRawFd for io::PipeReader {
fn into_raw_fd(self) -> RawFd {
self.0.into_raw_fd()
}
}

#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")]
impl AsRawFd for io::PipeWriter {
fn as_raw_fd(&self) -> RawFd {
self.0.as_raw_fd()
}
}

#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")]
impl FromRawFd for io::PipeWriter {
unsafe fn from_raw_fd(raw_fd: RawFd) -> Self {
Self::from_inner(unsafe { FromRawFd::from_raw_fd(raw_fd) })
}
}

#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")]
impl IntoRawFd for io::PipeWriter {
fn into_raw_fd(self) -> RawFd {
self.0.into_raw_fd()
}
}
42 changes: 42 additions & 0 deletions library/std/src/os/windows/io/handle.rs
Original file line number Diff line number Diff line change
@@ -660,3 +660,45 @@ impl<T> From<crate::thread::JoinHandle<T>> for OwnedHandle {
join_handle.into_inner().into_handle().into_inner()
}
}

#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")]
impl AsHandle for io::PipeReader {
fn as_handle(&self) -> BorrowedHandle<'_> {
self.0.as_handle()
}
}

#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")]
impl From<io::PipeReader> for OwnedHandle {
fn from(pipe: io::PipeReader) -> Self {
pipe.into_inner().into_inner()
}
}

#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")]
impl AsHandle for io::PipeWriter {
fn as_handle(&self) -> BorrowedHandle<'_> {
self.0.as_handle()
}
}

#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")]
impl From<io::PipeWriter> for OwnedHandle {
fn from(pipe: io::PipeWriter) -> Self {
pipe.into_inner().into_inner()
}
}

#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")]
impl From<OwnedHandle> for io::PipeReader {
fn from(owned_handle: OwnedHandle) -> Self {
Self::from_inner(FromInner::from_inner(owned_handle))
}
}

#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")]
impl From<OwnedHandle> for io::PipeWriter {
fn from(owned_handle: OwnedHandle) -> Self {
Self::from_inner(FromInner::from_inner(owned_handle))
}
}
42 changes: 42 additions & 0 deletions library/std/src/os/windows/io/raw.rs
Original file line number Diff line number Diff line change
@@ -310,3 +310,45 @@ impl IntoRawSocket for net::UdpSocket {
self.into_inner().into_socket().into_inner().into_raw_socket()
}
}

#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")]
impl AsRawHandle for io::PipeReader {
fn as_raw_handle(&self) -> RawHandle {
self.0.as_raw_handle()
}
}

#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")]
impl FromRawHandle for io::PipeReader {
unsafe fn from_raw_handle(raw_handle: RawHandle) -> Self {
unsafe { Self::from_inner(FromRawHandle::from_raw_handle(raw_handle)) }
}
}

#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")]
impl IntoRawHandle for io::PipeReader {
fn into_raw_handle(self) -> RawHandle {
self.0.into_raw_handle()
}
}

#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")]
impl AsRawHandle for io::PipeWriter {
fn as_raw_handle(&self) -> RawHandle {
self.0.as_raw_handle()
}
}

#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")]
impl FromRawHandle for io::PipeWriter {
unsafe fn from_raw_handle(raw_handle: RawHandle) -> Self {
unsafe { Self::from_inner(FromRawHandle::from_raw_handle(raw_handle)) }
}
}

#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")]
impl IntoRawHandle for io::PipeWriter {
fn into_raw_handle(self) -> RawHandle {
self.0.into_raw_handle()
}
}
14 changes: 14 additions & 0 deletions library/std/src/process.rs
Original file line number Diff line number Diff line change
@@ -1659,6 +1659,20 @@ impl From<io::Stderr> for Stdio {
}
}

#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")]
impl From<io::PipeWriter> for Stdio {
fn from(pipe: io::PipeWriter) -> Self {
Stdio::from_inner(pipe.into_inner().into())
}
}

#[stable(feature = "anonymous_pipe", since = "CURRENT_RUSTC_VERSION")]
impl From<io::PipeReader> for Stdio {
fn from(pipe: io::PipeReader) -> Self {
Stdio::from_inner(pipe.into_inner().into())
}
}

/// Describes the result of a process after it has terminated.
///
/// This `struct` is used to represent the exit status or other termination of a child process.
Loading
Loading