winpipe/lib.rs
1//! # winpipe
2//! Blocking wrapper for Windows named pipes with very similar api to UnixStream/UnixListen.
3//!
4//!
5//! ## Listening for a pipe (server)
6//! ```rust
7//! use winpipe::WinListener;
8//! use std::io;
9//!
10//! use std::io::{Read, Write};
11//!
12//! use std::time::Duration;
13//!
14//! fn listen_for_pipes() -> io::Result<()>{
15//! let listener = WinListener::bind("\\\\.\\pipe\\my_pipe_is_cool")?;
16//!
17//! loop {
18//! let (mut stream, _addr) = listener.accept()?;
19//! stream.set_write_timeout(Some(Duration::from_millis(5000)))?;
20//! stream.set_read_timeout(Some(Duration::from_millis(5000)))?;
21//!
22//! stream.write("Hello World".as_bytes())?;
23//! let mut buffer = vec![0u8; 64];
24//! let received = stream.read(buffer.as_mut_slice())?;
25//! println!("Received {:?}", &buffer[..received])
26//! //DROPPING Closes the pipe
27//! }
28//! }
29//! ```
30//! ## Connecting a pipe
31//! ```rust
32//! use winpipe::WinStream;
33//! use std::io;
34//!
35//! use std::io::{Read, Write};
36//!
37//! use std::time::Duration;
38//!
39//! fn connect_pipe() -> io::Result<()>{
40//! let mut stream = WinStream::connect("\\\\.\\pipe\\my_pipe_is_cool")?;
41//!
42//! stream.set_write_timeout(Some(Duration::from_millis(5000)))?;
43//! stream.set_read_timeout(Some(Duration::from_millis(5000)))?;
44//!
45//! stream.write("Hello World".as_bytes())?;
46//! let mut buffer = vec![0u8; 64];
47//! let received = stream.read(buffer.as_mut_slice())?;
48//! println!("Received {:?}", &buffer[..received]);
49//! //DROPPING Closes the pipe
50//! Ok(())
51//! }
52//! ```
53//! ## Tip for writing the same IPC code for Windows and Unix
54//! Create type aliases for UnixListen, UnixStream and unix::SocketAddress.
55//! On Unix targets let the alias point to the implementations of the stdlib.
56//! On Windows targets let the alias point to WinListen, WinStream and WinPipeSocketAddress.
57//!
58//! You should only require very few conditional compilation blocks as long as you do not use
59//! the advanced features of Unix Sockets (such as for example sharing file descriptors).
60//!
61//! ## Implementation Details
62//! * All pipes are created/opened by this crate are PIPE_TYPE_STREAM. PIPE_TYPE_PACKET is not implemented.
63//! * The default timeout for both read and write is infinite.
64//! * Setting a timeout or calling WinStream::set_nonblocking(true) concurrently will interrupt ongoing read/write calls.
65//! * Dropping WinStream may block up to 5s in a call to FlushFileBuffers.
66//! * The io buffer sizes supplied to the Windows API are 0x1_00_00 (64kb)
67//! * There is no connection backlog
68//! * It's not possible to implement one given Windows API limitations.
69//! * As long as you do not actively call WinListener::accept() or WinListener::incoming()::next() no client will be able to connect.
70//! * Connecting client pipes is implemented using CreateFileA and 200ms polling. It will try to connect for 1s (~4-5 times) before returning ErrorKind::ConnectionRefused
71//! * a custom timeout can be passed with `WinStream::connect_with_timeout`. At least 1 attempt to connect will always be made!
72//! * This library uses the `log` crate to log all system calls using the trace! macro.
73//! * If you are troubleshooting problems then I recommend using a log format which includes the thread id!
74//! + To disable usage of the log crate use default-features=false in your Cargo.toml when including winpipe.
75//!
76#[cfg(target_os = "windows")]
77mod pipe;
78#[cfg(target_os = "windows")]
79pub use pipe::*;