Initial implementation of anonymous_pipe
Co-authored-by: Alphyr <47725341+a1phyr@users.noreply.github.com> Co-authored-by: Jubilee <46493976+workingjubilee@users.noreply.github.com> Signed-off-by: Jiahao XU <Jiahao_XU@outlook.com>
This commit is contained in:
parent
52f3c71c8d
commit
c9c8a14884
17 changed files with 551 additions and 16 deletions
|
@ -590,6 +590,8 @@ pub mod panic;
|
|||
#[unstable(feature = "core_pattern_types", issue = "none")]
|
||||
pub mod pat;
|
||||
pub mod path;
|
||||
#[unstable(feature = "anonymous_pipe", issue = "127154")]
|
||||
pub mod pipe;
|
||||
pub mod process;
|
||||
pub mod sync;
|
||||
pub mod time;
|
||||
|
|
130
library/std/src/pipe.rs
Normal file
130
library/std/src/pipe.rs
Normal file
|
@ -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()
|
||||
}
|
||||
}
|
18
library/std/src/sys/anonymous_pipe/mod.rs
Normal file
18
library/std/src/sys/anonymous_pipe/mod.rs
Normal file
|
@ -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};
|
||||
}
|
||||
}
|
20
library/std/src/sys/anonymous_pipe/tests.rs
Normal file
20
library/std/src/sys/anonymous_pipe/tests.rs
Normal file
|
@ -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");
|
||||
}
|
103
library/std/src/sys/anonymous_pipe/unix.rs
Normal file
103
library/std/src/sys/anonymous_pipe/unix.rs
Normal file
|
@ -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))
|
||||
}
|
||||
}
|
26
library/std/src/sys/anonymous_pipe/unsupported.rs
Normal file
26
library/std/src/sys/anonymous_pipe/unsupported.rs
Normal file
|
@ -0,0 +1,26 @@
|
|||
use crate::{
|
||||
io,
|
||||
pipe::{PipeReader, PipeWriter},
|
||||
process::Stdio,
|
||||
};
|
||||
|
||||
pub(crate) use crate::sys::pipe::AnonPipe;
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn pipe() -> io::Result<(AnonPipe, AnonPipe)> {
|
||||
Err(io::Error::UNSUPPORTED_PLATFORM)
|
||||
}
|
||||
|
||||
#[unstable(feature = "anonymous_pipe", issue = "127154")]
|
||||
impl From<PipeReader> for Stdio {
|
||||
fn from(pipe: PipeReader) -> Self {
|
||||
pipe.0.diverge()
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "anonymous_pipe", issue = "127154")]
|
||||
impl From<PipeWriter> for Stdio {
|
||||
fn from(pipe: PipeWriter) -> Self {
|
||||
pipe.0.diverge()
|
||||
}
|
||||
}
|
109
library/std/src/sys/anonymous_pipe/windows.rs
Normal file
109
library/std/src/sys/anonymous_pipe/windows.rs
Normal file
|
@ -0,0 +1,109 @@
|
|||
use crate::{
|
||||
io,
|
||||
os::windows::io::{
|
||||
AsHandle, AsRawHandle, BorrowedHandle, FromRawHandle, IntoRawHandle, OwnedHandle, RawHandle,
|
||||
},
|
||||
pipe::{PipeReader, PipeWriter},
|
||||
process::Stdio,
|
||||
sys::{handle::Handle, pipe::unnamed_anon_pipe},
|
||||
sys_common::{FromInner, IntoInner},
|
||||
};
|
||||
|
||||
pub(crate) type AnonPipe = Handle;
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn pipe() -> io::Result<(AnonPipe, AnonPipe)> {
|
||||
unnamed_anon_pipe().map(|(rx, wx)| (rx.into_inner(), wx.into_inner()))
|
||||
}
|
||||
|
||||
#[unstable(feature = "anonymous_pipe", issue = "127154")]
|
||||
impl AsHandle for PipeReader {
|
||||
fn as_handle(&self) -> BorrowedHandle<'_> {
|
||||
self.0.as_handle()
|
||||
}
|
||||
}
|
||||
#[unstable(feature = "anonymous_pipe", issue = "127154")]
|
||||
impl AsRawHandle for PipeReader {
|
||||
fn as_raw_handle(&self) -> RawHandle {
|
||||
self.0.as_raw_handle()
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "anonymous_pipe", issue = "127154")]
|
||||
impl FromRawHandle for PipeReader {
|
||||
unsafe fn from_raw_handle(raw_handle: RawHandle) -> Self {
|
||||
Self(Handle::from_raw_handle(raw_handle))
|
||||
}
|
||||
}
|
||||
#[unstable(feature = "anonymous_pipe", issue = "127154")]
|
||||
impl IntoRawHandle for PipeReader {
|
||||
fn into_raw_handle(self) -> RawHandle {
|
||||
self.0.into_raw_handle()
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "anonymous_pipe", issue = "127154")]
|
||||
impl From<PipeReader> for OwnedHandle {
|
||||
fn from(pipe: PipeReader) -> Self {
|
||||
Handle::into_inner(pipe.0)
|
||||
}
|
||||
}
|
||||
#[unstable(feature = "anonymous_pipe", issue = "127154")]
|
||||
impl From<PipeReader> for Stdio {
|
||||
fn from(pipe: PipeReader) -> Self {
|
||||
Self::from(OwnedHandle::from(pipe))
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "anonymous_pipe", issue = "127154")]
|
||||
impl AsHandle for PipeWriter {
|
||||
fn as_handle(&self) -> BorrowedHandle<'_> {
|
||||
self.0.as_handle()
|
||||
}
|
||||
}
|
||||
#[unstable(feature = "anonymous_pipe", issue = "127154")]
|
||||
impl AsRawHandle for PipeWriter {
|
||||
fn as_raw_handle(&self) -> RawHandle {
|
||||
self.0.as_raw_handle()
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "anonymous_pipe", issue = "127154")]
|
||||
impl FromRawHandle for PipeWriter {
|
||||
unsafe fn from_raw_handle(raw_handle: RawHandle) -> Self {
|
||||
Self(Handle::from_raw_handle(raw_handle))
|
||||
}
|
||||
}
|
||||
#[unstable(feature = "anonymous_pipe", issue = "127154")]
|
||||
impl IntoRawHandle for PipeWriter {
|
||||
fn into_raw_handle(self) -> RawHandle {
|
||||
self.0.into_raw_handle()
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "anonymous_pipe", issue = "127154")]
|
||||
impl From<PipeWriter> for OwnedHandle {
|
||||
fn from(pipe: PipeWriter) -> Self {
|
||||
Handle::into_inner(pipe.0)
|
||||
}
|
||||
}
|
||||
#[unstable(feature = "anonymous_pipe", issue = "127154")]
|
||||
impl From<PipeWriter> for Stdio {
|
||||
fn from(pipe: PipeWriter) -> Self {
|
||||
Self::from(OwnedHandle::from(pipe))
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "anonymous_pipe", issue = "127154")]
|
||||
impl From<OwnedHandle> for PipeReader {
|
||||
fn from(owned_handle: OwnedHandle) -> Self {
|
||||
Self(Handle::from_inner(owned_handle))
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "anonymous_pipe", issue = "127154")]
|
||||
impl From<OwnedHandle> for PipeWriter {
|
||||
fn from(owned_handle: OwnedHandle) -> Self {
|
||||
Self(Handle::from_inner(owned_handle))
|
||||
}
|
||||
}
|
|
@ -7,6 +7,8 @@ mod pal;
|
|||
|
||||
mod personality;
|
||||
|
||||
#[unstable(feature = "anonymous_pipe", issue = "127154")]
|
||||
pub mod anonymous_pipe;
|
||||
pub mod backtrace;
|
||||
pub mod cmath;
|
||||
pub mod exit_guard;
|
||||
|
|
|
@ -82,6 +82,11 @@ const fn max_iov() -> usize {
|
|||
}
|
||||
|
||||
impl FileDesc {
|
||||
#[inline]
|
||||
pub fn try_clone(&self) -> io::Result<Self> {
|
||||
self.duplicate()
|
||||
}
|
||||
|
||||
pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
|
||||
let ret = cvt(unsafe {
|
||||
libc::read(
|
||||
|
|
|
@ -9,6 +9,7 @@ use crate::sys_common::{FromInner, IntoInner};
|
|||
// Anonymous pipes
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct AnonPipe(FileDesc);
|
||||
|
||||
pub fn anon_pipe() -> io::Result<(AnonPipe, AnonPipe)> {
|
||||
|
@ -46,6 +47,10 @@ pub fn anon_pipe() -> io::Result<(AnonPipe, AnonPipe)> {
|
|||
}
|
||||
|
||||
impl AnonPipe {
|
||||
pub fn try_clone(&self) -> io::Result<Self> {
|
||||
self.0.duplicate().map(Self)
|
||||
}
|
||||
|
||||
pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
|
||||
self.0.read(buf)
|
||||
}
|
||||
|
@ -79,6 +84,10 @@ impl AnonPipe {
|
|||
pub fn is_write_vectored(&self) -> bool {
|
||||
self.0.is_write_vectored()
|
||||
}
|
||||
|
||||
pub fn as_file_desc(&self) -> &FileDesc {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoInner<FileDesc> for AnonPipe {
|
||||
|
|
|
@ -1,8 +1,21 @@
|
|||
use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut};
|
||||
use crate::{
|
||||
fmt,
|
||||
io::{self, BorrowedCursor, IoSlice, IoSliceMut},
|
||||
};
|
||||
|
||||
pub struct AnonPipe(!);
|
||||
|
||||
impl fmt::Debug for AnonPipe {
|
||||
fn fmt(&self, _: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl AnonPipe {
|
||||
pub fn try_clone(&self) -> io::Result<Self> {
|
||||
self.0
|
||||
}
|
||||
|
||||
pub fn read(&self, _buf: &mut [u8]) -> io::Result<usize> {
|
||||
self.0
|
||||
}
|
||||
|
|
|
@ -2462,6 +2462,7 @@ Windows.Win32.System.LibraryLoader.GetProcAddress
|
|||
Windows.Win32.System.Performance.QueryPerformanceCounter
|
||||
Windows.Win32.System.Performance.QueryPerformanceFrequency
|
||||
Windows.Win32.System.Pipes.CreateNamedPipeW
|
||||
Windows.Win32.System.Pipes.CreatePipe
|
||||
Windows.Win32.System.Pipes.NAMED_PIPE_MODE
|
||||
Windows.Win32.System.Pipes.PIPE_ACCEPT_REMOTE_CLIENTS
|
||||
Windows.Win32.System.Pipes.PIPE_CLIENT_END
|
||||
|
|
|
@ -14,6 +14,7 @@ windows_targets::link!("kernel32.dll" "system" fn CreateEventW(lpeventattributes
|
|||
windows_targets::link!("kernel32.dll" "system" fn CreateFileW(lpfilename : PCWSTR, dwdesiredaccess : u32, dwsharemode : FILE_SHARE_MODE, lpsecurityattributes : *const SECURITY_ATTRIBUTES, dwcreationdisposition : FILE_CREATION_DISPOSITION, dwflagsandattributes : FILE_FLAGS_AND_ATTRIBUTES, htemplatefile : HANDLE) -> HANDLE);
|
||||
windows_targets::link!("kernel32.dll" "system" fn CreateHardLinkW(lpfilename : PCWSTR, lpexistingfilename : PCWSTR, lpsecurityattributes : *const SECURITY_ATTRIBUTES) -> BOOL);
|
||||
windows_targets::link!("kernel32.dll" "system" fn CreateNamedPipeW(lpname : PCWSTR, dwopenmode : FILE_FLAGS_AND_ATTRIBUTES, dwpipemode : NAMED_PIPE_MODE, nmaxinstances : u32, noutbuffersize : u32, ninbuffersize : u32, ndefaulttimeout : u32, lpsecurityattributes : *const SECURITY_ATTRIBUTES) -> HANDLE);
|
||||
windows_targets::link!("kernel32.dll" "system" fn CreatePipe(hreadpipe : *mut HANDLE, hwritepipe : *mut HANDLE, lppipeattributes : *const SECURITY_ATTRIBUTES, nsize : u32) -> BOOL);
|
||||
windows_targets::link!("kernel32.dll" "system" fn CreateProcessW(lpapplicationname : PCWSTR, lpcommandline : PWSTR, lpprocessattributes : *const SECURITY_ATTRIBUTES, lpthreadattributes : *const SECURITY_ATTRIBUTES, binherithandles : BOOL, dwcreationflags : PROCESS_CREATION_FLAGS, lpenvironment : *const core::ffi::c_void, lpcurrentdirectory : PCWSTR, lpstartupinfo : *const STARTUPINFOW, lpprocessinformation : *mut PROCESS_INFORMATION) -> BOOL);
|
||||
windows_targets::link!("kernel32.dll" "system" fn CreateSymbolicLinkW(lpsymlinkfilename : PCWSTR, lptargetfilename : PCWSTR, dwflags : SYMBOLIC_LINK_FLAGS) -> BOOLEAN);
|
||||
windows_targets::link!("kernel32.dll" "system" fn CreateThread(lpthreadattributes : *const SECURITY_ATTRIBUTES, dwstacksize : usize, lpstartaddress : LPTHREAD_START_ROUTINE, lpparameter : *const core::ffi::c_void, dwcreationflags : THREAD_CREATION_FLAGS, lpthreadid : *mut u32) -> HANDLE);
|
||||
|
|
|
@ -17,6 +17,7 @@ use crate::sys_common::{AsInner, FromInner, IntoInner};
|
|||
/// An owned container for `HANDLE` object, closing them on Drop.
|
||||
///
|
||||
/// All methods are inherited through a `Deref` impl to `RawHandle`
|
||||
#[derive(Debug)]
|
||||
pub struct Handle(OwnedHandle);
|
||||
|
||||
impl Handle {
|
||||
|
@ -136,6 +137,12 @@ impl Handle {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn read_to_end(&self, buf: &mut Vec<u8>) -> io::Result<usize> {
|
||||
let mut me = self;
|
||||
|
||||
Read::read_to_end(&mut me, buf)
|
||||
}
|
||||
|
||||
pub unsafe fn read_overlapped(
|
||||
&self,
|
||||
buf: &mut [mem::MaybeUninit<u8>],
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use crate::os::windows::prelude::*;
|
||||
|
||||
use crate::ffi::OsStr;
|
||||
use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut, Read};
|
||||
use crate::io::{self, BorrowedCursor, IoSlice, IoSliceMut};
|
||||
use crate::mem;
|
||||
use crate::path::Path;
|
||||
use crate::ptr;
|
||||
|
@ -39,6 +39,23 @@ pub struct Pipes {
|
|||
pub theirs: AnonPipe,
|
||||
}
|
||||
|
||||
/// Create true unnamed anonymous pipe.
|
||||
pub fn unnamed_anon_pipe() -> io::Result<(AnonPipe, AnonPipe)> {
|
||||
let mut read_pipe = c::INVALID_HANDLE_VALUE;
|
||||
let mut write_pipe = c::INVALID_HANDLE_VALUE;
|
||||
|
||||
let ret = unsafe { c::CreatePipe(&mut read_pipe, &mut write_pipe, ptr::null_mut(), 0) };
|
||||
|
||||
if ret == 0 {
|
||||
Err(io::Error::last_os_error())
|
||||
} else {
|
||||
Ok((
|
||||
AnonPipe::from_inner(unsafe { Handle::from_raw_handle(read_pipe) }),
|
||||
AnonPipe::from_inner(unsafe { Handle::from_raw_handle(write_pipe) }),
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
/// Although this looks similar to `anon_pipe` in the Unix module it's actually
|
||||
/// subtly different. Here we'll return two pipes in the `Pipes` return value,
|
||||
/// but one is intended for "us" where as the other is intended for "someone
|
||||
|
@ -181,7 +198,7 @@ pub fn spawn_pipe_relay(
|
|||
their_handle_inheritable: bool,
|
||||
) -> io::Result<AnonPipe> {
|
||||
// We need this handle to live for the lifetime of the thread spawned below.
|
||||
let source = source.duplicate()?;
|
||||
let source = source.try_clone()?;
|
||||
|
||||
// create a new pair of anon pipes.
|
||||
let Pipes { theirs, ours } = anon_pipe(ours_readable, their_handle_inheritable)?;
|
||||
|
@ -237,7 +254,8 @@ impl AnonPipe {
|
|||
pub fn into_handle(self) -> Handle {
|
||||
self.inner
|
||||
}
|
||||
fn duplicate(&self) -> io::Result<Self> {
|
||||
|
||||
pub fn try_clone(&self) -> io::Result<Self> {
|
||||
self.inner.duplicate(0, false, c::DUPLICATE_SAME_ACCESS).map(|inner| AnonPipe { inner })
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue