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
|
|
@ -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