use std::os::windows::io::{AsRawHandle, FromRawHandle, OwnedHandle, RawHandle};
use std::{io, ptr};
use windows_sys::Win32::Foundation::{HANDLE, INVALID_HANDLE_VALUE};
use windows_sys::Win32::System::Pipes::CreatePipe;
#[derive(Debug)]
pub struct PipePair {
pub read: OwnedHandle,
pub write: OwnedHandle,
}
impl PipePair {
pub fn new() -> io::Result<Self> {
let mut read_handle: HANDLE = INVALID_HANDLE_VALUE;
let mut write_handle: HANDLE = INVALID_HANDLE_VALUE;
let result = unsafe { CreatePipe(&mut read_handle, &mut write_handle, ptr::null(), 0) };
if result == 0 {
return Err(io::Error::last_os_error());
}
Ok(Self {
read: unsafe { OwnedHandle::from_raw_handle(read_handle as RawHandle) },
write: unsafe { OwnedHandle::from_raw_handle(write_handle as RawHandle) },
})
}
}
pub fn create_input_pipe() -> io::Result<PipePair> {
PipePair::new()
}
pub fn create_output_pipe() -> io::Result<PipePair> {
PipePair::new()
}
pub fn set_inheritable(handle: &OwnedHandle, inheritable: bool) -> io::Result<()> {
use windows_sys::Win32::Foundation::{HANDLE_FLAG_INHERIT, SetHandleInformation};
let flags = if inheritable { HANDLE_FLAG_INHERIT } else { 0 };
let result = unsafe {
SetHandleInformation(handle.as_raw_handle() as HANDLE, HANDLE_FLAG_INHERIT, flags)
};
if result == 0 {
Err(io::Error::last_os_error())
} else {
Ok(())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn create_pipe_pair() {
let pair = PipePair::new();
assert!(pair.is_ok());
}
}