use std::io;
use std::mem::size_of;
use std::os::windows::io::{FromRawHandle, OwnedHandle};
use std::ptr;
use windows_sys::Win32::Foundation::HANDLE;
use windows_sys::Win32::Security::SECURITY_ATTRIBUTES;
use windows_sys::Win32::System::Pipes::CreatePipe;
#[derive(Debug)]
pub(crate) struct SyncPipes {
pub(crate) conout_read: OwnedHandle,
pub(crate) conout_write: OwnedHandle,
pub(crate) conin_read: OwnedHandle,
pub(crate) conin_write: OwnedHandle,
}
pub(crate) fn create_sync_pipes() -> io::Result<SyncPipes> {
let (conout_read, conout_write) = create_pipe()?;
let (conin_read, conin_write) = create_pipe()?;
Ok(SyncPipes {
conout_read,
conout_write,
conin_read,
conin_write,
})
}
fn create_pipe() -> io::Result<(OwnedHandle, OwnedHandle)> {
let attributes = non_inheritable_attributes();
let mut read: HANDLE = ptr::null_mut();
let mut write: HANDLE = ptr::null_mut();
let created = unsafe { CreatePipe(&mut read, &mut write, &attributes, 0) };
if created == 0 {
return Err(io::Error::last_os_error());
}
let read = unsafe { OwnedHandle::from_raw_handle(read) };
let write = unsafe { OwnedHandle::from_raw_handle(write) };
Ok((read, write))
}
fn non_inheritable_attributes() -> SECURITY_ATTRIBUTES {
SECURITY_ATTRIBUTES {
nLength: u32::try_from(size_of::<SECURITY_ATTRIBUTES>()).unwrap_or(u32::MAX),
lpSecurityDescriptor: ptr::null_mut(),
bInheritHandle: 0,
}
}
#[cfg(test)]
#[path = "anonymous_tests.rs"]
mod tests;