-
Notifications
You must be signed in to change notification settings - Fork 12.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Auto merge of #127153 - NobodyXu:pipe, r=ChrisDenton
Initial implementation of anonymous_pipe API ACP completed in rust-lang/libs-team#375 Tracking issue: #127154 try-job: x86_64-msvc try-job: i686-mingw
- Loading branch information
Showing
17 changed files
with
551 additions
and
16 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
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,130 @@ | ||
//! 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::anonymous_pipe::{pipe as pipe_inner, 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)> { | ||
pipe_inner().map(|(reader, writer)| (PipeReader(reader), PipeWriter(writer))) | ||
} | ||
|
||
/// Read end of the anonymous pipe. | ||
#[unstable(feature = "anonymous_pipe", issue = "127154")] | ||
#[derive(Debug)] | ||
pub struct PipeReader(pub(crate) AnonPipe); | ||
|
||
/// Write end of the anonymous pipe. | ||
#[unstable(feature = "anonymous_pipe", issue = "127154")] | ||
#[derive(Debug)] | ||
pub struct PipeWriter(pub(crate) 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() | ||
} | ||
} |
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,18 @@ | ||
cfg_if::cfg_if! { | ||
if #[cfg(unix)] { | ||
mod unix; | ||
pub(crate) use unix::{AnonPipe, pipe}; | ||
|
||
#[cfg(all(test, not(miri)))] | ||
mod tests; | ||
} else if #[cfg(windows)] { | ||
mod windows; | ||
pub(crate) use windows::{AnonPipe, pipe}; | ||
|
||
#[cfg(all(test, not(miri)))] | ||
mod tests; | ||
} else { | ||
mod unsupported; | ||
pub(crate) use unsupported::{AnonPipe, pipe}; | ||
} | ||
} |
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,20 @@ | ||
use crate::{ | ||
io::{Read, Write}, | ||
pipe::pipe, | ||
}; | ||
|
||
#[test] | ||
fn pipe_creation_clone_and_rw() { | ||
let (rx, tx) = pipe().unwrap(); | ||
|
||
tx.try_clone().unwrap().write_all(b"12345").unwrap(); | ||
drop(tx); | ||
|
||
let mut rx2 = rx.try_clone().unwrap(); | ||
drop(rx); | ||
|
||
let mut s = String::new(); | ||
rx2.read_to_string(&mut s).unwrap(); | ||
drop(rx2); | ||
assert_eq!(s, "12345"); | ||
} |
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,103 @@ | ||
use crate::{ | ||
io, | ||
os::fd::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, OwnedFd, RawFd}, | ||
pipe::{PipeReader, PipeWriter}, | ||
process::Stdio, | ||
sys::{fd::FileDesc, pipe::anon_pipe}, | ||
sys_common::{FromInner, IntoInner}, | ||
}; | ||
|
||
pub(crate) type AnonPipe = FileDesc; | ||
|
||
#[inline] | ||
pub(crate) fn pipe() -> io::Result<(AnonPipe, AnonPipe)> { | ||
anon_pipe().map(|(rx, wx)| (rx.into_inner(), wx.into_inner())) | ||
} | ||
|
||
#[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(pipe.0) | ||
} | ||
} | ||
#[unstable(feature = "anonymous_pipe", issue = "127154")] | ||
impl FromRawFd for PipeReader { | ||
unsafe fn from_raw_fd(raw_fd: RawFd) -> Self { | ||
Self(FileDesc::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(pipe.0) | ||
} | ||
} | ||
#[unstable(feature = "anonymous_pipe", issue = "127154")] | ||
impl FromRawFd for PipeWriter { | ||
unsafe fn from_raw_fd(raw_fd: RawFd) -> Self { | ||
Self(FileDesc::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)) | ||
} | ||
} | ||
|
||
#[unstable(feature = "anonymous_pipe", issue = "127154")] | ||
impl From<OwnedFd> for PipeReader { | ||
fn from(owned_fd: OwnedFd) -> Self { | ||
Self(FileDesc::from_inner(owned_fd)) | ||
} | ||
} | ||
|
||
#[unstable(feature = "anonymous_pipe", issue = "127154")] | ||
impl From<OwnedFd> for PipeWriter { | ||
fn from(owned_fd: OwnedFd) -> Self { | ||
Self(FileDesc::from_inner(owned_fd)) | ||
} | ||
} |
Oops, something went wrong.