forked from rust-lang/rust
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Rollup merge of rust-lang#127153 - NobodyXu:pipe, r=jhpratt
Initial implementation of anonymous_pipe API ACP completed in rust-lang/libs-team#375 Tracking issue: rust-lang#127154
- Loading branch information
Showing
10 changed files
with
428 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,144 @@ | ||
//! Module for anonymous pipe | ||
//! | ||
//! ``` | ||
//! #![feature(anonymous_pipe)] | ||
//! | ||
//! # #[cfg(miri)] fn main() {} | ||
//! # #[cfg(not(miri))] | ||
//! # fn main() -> std::io::Result<()> { | ||
//! let (reader, writer) = std::pipe::pipe()?; | ||
//! # Ok(()) | ||
//! # } | ||
//! ``` | ||
|
||
use crate::{io, sys::pipe::AnonPipe}; | ||
|
||
/// Create anonymous pipe that is close-on-exec and blocking. | ||
#[unstable(feature = "anonymous_pipe", issue = "127154")] | ||
#[inline] | ||
pub fn pipe() -> io::Result<(PipeReader, PipeWriter)> { | ||
cfg_if::cfg_if! { | ||
if #[cfg(unix)] { | ||
unix::pipe() | ||
} else if #[cfg(windows)] { | ||
windows::pipe() | ||
} else { | ||
Err(io::Error::UNSUPPORTED_PLATFORM) | ||
} | ||
} | ||
} | ||
|
||
/// Read end of the anonymous pipe. | ||
#[unstable(feature = "anonymous_pipe", issue = "127154")] | ||
#[derive(Debug)] | ||
pub struct PipeReader(AnonPipe); | ||
|
||
/// Write end of the anonymous pipe. | ||
#[unstable(feature = "anonymous_pipe", issue = "127154")] | ||
#[derive(Debug)] | ||
pub struct PipeWriter(AnonPipe); | ||
|
||
impl PipeReader { | ||
/// Create a new [`PipeReader`] instance that shares the same underlying file description. | ||
#[unstable(feature = "anonymous_pipe", issue = "127154")] | ||
pub fn try_clone(&self) -> io::Result<Self> { | ||
self.0.try_clone().map(Self) | ||
} | ||
} | ||
|
||
impl PipeWriter { | ||
/// Create a new [`PipeWriter`] instance that shares the same underlying file description. | ||
#[unstable(feature = "anonymous_pipe", issue = "127154")] | ||
pub fn try_clone(&self) -> io::Result<Self> { | ||
self.0.try_clone().map(Self) | ||
} | ||
} | ||
|
||
#[unstable(feature = "anonymous_pipe", issue = "127154")] | ||
impl io::Read for &PipeReader { | ||
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { | ||
self.0.read(buf) | ||
} | ||
fn read_vectored(&mut self, bufs: &mut [io::IoSliceMut<'_>]) -> io::Result<usize> { | ||
self.0.read_vectored(bufs) | ||
} | ||
#[inline] | ||
fn is_read_vectored(&self) -> bool { | ||
self.0.is_read_vectored() | ||
} | ||
fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> { | ||
self.0.read_to_end(buf) | ||
} | ||
fn read_buf(&mut self, buf: io::BorrowedCursor<'_>) -> io::Result<()> { | ||
self.0.read_buf(buf) | ||
} | ||
} | ||
|
||
#[unstable(feature = "anonymous_pipe", issue = "127154")] | ||
impl io::Read for PipeReader { | ||
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { | ||
self.0.read(buf) | ||
} | ||
fn read_vectored(&mut self, bufs: &mut [io::IoSliceMut<'_>]) -> io::Result<usize> { | ||
self.0.read_vectored(bufs) | ||
} | ||
#[inline] | ||
fn is_read_vectored(&self) -> bool { | ||
self.0.is_read_vectored() | ||
} | ||
fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> { | ||
self.0.read_to_end(buf) | ||
} | ||
fn read_buf(&mut self, buf: io::BorrowedCursor<'_>) -> io::Result<()> { | ||
self.0.read_buf(buf) | ||
} | ||
} | ||
|
||
#[unstable(feature = "anonymous_pipe", issue = "127154")] | ||
impl io::Write for &PipeWriter { | ||
fn write(&mut self, buf: &[u8]) -> io::Result<usize> { | ||
self.0.write(buf) | ||
} | ||
#[inline] | ||
fn flush(&mut self) -> io::Result<()> { | ||
Ok(()) | ||
} | ||
|
||
fn write_vectored(&mut self, bufs: &[io::IoSlice<'_>]) -> io::Result<usize> { | ||
self.0.write_vectored(bufs) | ||
} | ||
|
||
#[inline] | ||
fn is_write_vectored(&self) -> bool { | ||
self.0.is_write_vectored() | ||
} | ||
} | ||
|
||
#[unstable(feature = "anonymous_pipe", issue = "127154")] | ||
impl io::Write for PipeWriter { | ||
fn write(&mut self, buf: &[u8]) -> io::Result<usize> { | ||
self.0.write(buf) | ||
} | ||
#[inline] | ||
fn flush(&mut self) -> io::Result<()> { | ||
Ok(()) | ||
} | ||
|
||
fn write_vectored(&mut self, bufs: &[io::IoSlice<'_>]) -> io::Result<usize> { | ||
self.0.write_vectored(bufs) | ||
} | ||
|
||
#[inline] | ||
fn is_write_vectored(&self) -> bool { | ||
self.0.is_write_vectored() | ||
} | ||
} | ||
|
||
#[cfg(unix)] | ||
mod unix; | ||
|
||
#[cfg(windows)] | ||
mod windows; | ||
|
||
#[cfg(all(test, not(miri)))] | ||
mod tests; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
use super::*; | ||
use crate::io::{Read, Write}; | ||
|
||
#[test] | ||
fn pipe_creation_and_rw() { | ||
let (mut rx, mut tx) = pipe().unwrap(); | ||
tx.write_all(b"12345").unwrap(); | ||
drop(tx); | ||
|
||
let mut s = String::new(); | ||
rx.read_to_string(&mut s).unwrap(); | ||
assert_eq!(s, "12345"); | ||
} | ||
|
||
#[test] | ||
fn pipe_try_clone_and_rw() { | ||
let (mut rx, mut tx) = pipe().unwrap(); | ||
tx.try_clone().unwrap().write_all(b"12").unwrap(); | ||
tx.write_all(b"345").unwrap(); | ||
drop(tx); | ||
|
||
let mut s = String::new(); | ||
rx.try_clone().unwrap().take(3).read_to_string(&mut s).unwrap(); | ||
assert_eq!(s, "123"); | ||
|
||
s.clear(); | ||
rx.read_to_string(&mut s).unwrap(); | ||
assert_eq!(s, "45"); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
use super::*; | ||
|
||
use crate::{ | ||
os::fd::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, OwnedFd, RawFd}, | ||
process::Stdio, | ||
sys::{ | ||
fd::FileDesc, | ||
pipe::{anon_pipe, AnonPipe}, | ||
}, | ||
sys_common::{FromInner, IntoInner}, | ||
}; | ||
|
||
#[inline] | ||
pub(super) fn pipe() -> io::Result<(PipeReader, PipeWriter)> { | ||
anon_pipe().map(|(rx, tx)| (PipeReader(rx), PipeWriter(tx))) | ||
} | ||
|
||
#[unstable(feature = "anonymous_pipe", issue = "127154")] | ||
impl AsFd for PipeReader { | ||
fn as_fd(&self) -> BorrowedFd<'_> { | ||
self.0.as_fd() | ||
} | ||
} | ||
#[unstable(feature = "anonymous_pipe", issue = "127154")] | ||
impl AsRawFd for PipeReader { | ||
fn as_raw_fd(&self) -> RawFd { | ||
self.0.as_raw_fd() | ||
} | ||
} | ||
#[unstable(feature = "anonymous_pipe", issue = "127154")] | ||
impl From<PipeReader> for OwnedFd { | ||
fn from(pipe: PipeReader) -> Self { | ||
FileDesc::into_inner(AnonPipe::into_inner(pipe.0)) | ||
} | ||
} | ||
#[unstable(feature = "anonymous_pipe", issue = "127154")] | ||
impl FromRawFd for PipeReader { | ||
unsafe fn from_raw_fd(raw_fd: RawFd) -> Self { | ||
Self(AnonPipe::from_raw_fd(raw_fd)) | ||
} | ||
} | ||
#[unstable(feature = "anonymous_pipe", issue = "127154")] | ||
impl IntoRawFd for PipeReader { | ||
fn into_raw_fd(self) -> RawFd { | ||
self.0.into_raw_fd() | ||
} | ||
} | ||
#[unstable(feature = "anonymous_pipe", issue = "127154")] | ||
impl From<PipeReader> for Stdio { | ||
fn from(pipe: PipeReader) -> Self { | ||
Self::from(OwnedFd::from(pipe)) | ||
} | ||
} | ||
|
||
#[unstable(feature = "anonymous_pipe", issue = "127154")] | ||
impl AsFd for PipeWriter { | ||
fn as_fd(&self) -> BorrowedFd<'_> { | ||
self.0.as_fd() | ||
} | ||
} | ||
#[unstable(feature = "anonymous_pipe", issue = "127154")] | ||
impl AsRawFd for PipeWriter { | ||
fn as_raw_fd(&self) -> RawFd { | ||
self.0.as_raw_fd() | ||
} | ||
} | ||
#[unstable(feature = "anonymous_pipe", issue = "127154")] | ||
impl From<PipeWriter> for OwnedFd { | ||
fn from(pipe: PipeWriter) -> Self { | ||
FileDesc::into_inner(AnonPipe::into_inner(pipe.0)) | ||
} | ||
} | ||
#[unstable(feature = "anonymous_pipe", issue = "127154")] | ||
impl FromRawFd for PipeWriter { | ||
unsafe fn from_raw_fd(raw_fd: RawFd) -> Self { | ||
Self(AnonPipe::from_raw_fd(raw_fd)) | ||
} | ||
} | ||
#[unstable(feature = "anonymous_pipe", issue = "127154")] | ||
impl IntoRawFd for PipeWriter { | ||
fn into_raw_fd(self) -> RawFd { | ||
self.0.into_raw_fd() | ||
} | ||
} | ||
#[unstable(feature = "anonymous_pipe", issue = "127154")] | ||
impl From<PipeWriter> for Stdio { | ||
fn from(pipe: PipeWriter) -> Self { | ||
Self::from(OwnedFd::from(pipe)) | ||
} | ||
} | ||
|
||
fn convert_to_pipe(owned_fd: OwnedFd) -> AnonPipe { | ||
AnonPipe::from_inner(FileDesc::from_inner(OwnedFd::from(owned_fd))) | ||
} | ||
|
||
#[unstable(feature = "anonymous_pipe", issue = "127154")] | ||
impl From<OwnedFd> for PipeReader { | ||
fn from(owned_fd: OwnedFd) -> Self { | ||
Self(convert_to_pipe(owned_fd)) | ||
} | ||
} | ||
|
||
#[unstable(feature = "anonymous_pipe", issue = "127154")] | ||
impl From<OwnedFd> for PipeWriter { | ||
fn from(owned_fd: OwnedFd) -> Self { | ||
Self(convert_to_pipe(owned_fd)) | ||
} | ||
} |
Oops, something went wrong.