6 use std
::os
::windows
::prelude
::*;
7 use std
::process
::Stdio
;
14 pub fn pipe() -> io
::Result
<(PipeReader
, PipeWriter
)> {
15 let mut read_pipe
: winapi
::HANDLE
= ptr
::null_mut();
16 let mut write_pipe
: winapi
::HANDLE
= ptr
::null_mut();
19 // TODO: These pipes do not support IOCP. We might want to emulate anonymous pipes with
20 // CreateNamedPipe, as Rust's stdlib does.
21 kernel32
::CreatePipe(&mut read_pipe
as winapi
::PHANDLE
,
22 &mut write_pipe
as winapi
::PHANDLE
,
28 Err(io
::Error
::last_os_error())
31 Ok((PipeReader
::from_raw_handle(read_pipe
), PipeWriter
::from_raw_handle(write_pipe
)))
36 pub fn parent_stdin() -> io
::Result
<Stdio
> {
37 dup_std_handle(winapi
::STD_INPUT_HANDLE
)
40 pub fn parent_stdout() -> io
::Result
<Stdio
> {
41 dup_std_handle(winapi
::STD_OUTPUT_HANDLE
)
44 pub fn parent_stderr() -> io
::Result
<Stdio
> {
45 dup_std_handle(winapi
::STD_ERROR_HANDLE
)
48 // adapted from src/libstd/sys/windows/stdio.rs
49 fn dup_std_handle(which
: winapi
::DWORD
) -> io
::Result
<Stdio
> {
50 let handle
= unsafe { kernel32::GetStdHandle(which) }
;
51 if handle
== winapi
::INVALID_HANDLE_VALUE
{
52 return Err(io
::Error
::last_os_error());
55 return Err(io
::Error
::new(io
::ErrorKind
::Other
,
56 "no stdio handle available for this process"));
58 // This handle is *not* a dup. It's just a copy of the global stdin/stdout/stderr handle, and
59 // we need to dup it ourselves. The simplest way to do that is File::try_clone(), but we need
60 // to make sure that the file is never dropped.
61 let temp_file
= unsafe { File::from_raw_handle(handle) }
;
62 let dup_result
= temp_file
.try_clone(); // No short-circuit here!
63 temp_file
.into_raw_handle(); // Prevent closing handle on drop().
64 dup_result
.map(File
::into_stdio
)
67 impl<T
: IntoRawHandle
> IntoStdio
for T
{
68 fn into_stdio(self) -> Stdio
{
69 let handle
= self.into_raw_handle();
70 unsafe { Stdio::from_raw_handle(handle) }
74 impl IntoRawHandle
for PipeReader
{
75 fn into_raw_handle(self) -> RawHandle
{
76 self.0.into_raw_handle
()
80 impl AsRawHandle
for PipeReader
{
81 fn as_raw_handle(&self) -> RawHandle
{
82 self.0.as_raw_handle()
86 impl FromRawHandle
for PipeReader
{
87 unsafe fn from_raw_handle(handle
: RawHandle
) -> PipeReader
{
88 PipeReader(File
::from_raw_handle(handle
))
92 impl IntoRawHandle
for PipeWriter
{
93 fn into_raw_handle(self) -> RawHandle
{
94 self.0.into_raw_handle
()
98 impl AsRawHandle
for PipeWriter
{
99 fn as_raw_handle(&self) -> RawHandle
{
100 self.0.as_raw_handle()
104 impl FromRawHandle
for PipeWriter
{
105 unsafe fn from_raw_handle(handle
: RawHandle
) -> PipeWriter
{
106 PipeWriter(File
::from_raw_handle(handle
))