|
6 | 6 | //! cargo run --example windows-uds
|
7 | 7 | //! ```
|
8 | 8 |
|
| 9 | +#[cfg(windows)] |
| 10 | +fn main() -> std::io::Result<()> { |
| 11 | + use std::ops::Deref; |
| 12 | + use std::os::windows::io::{AsRawSocket, AsSocket, BorrowedSocket}; |
| 13 | + use std::path::PathBuf; |
| 14 | + |
| 15 | + use async_io::Async; |
| 16 | + use blocking::Unblock; |
| 17 | + use futures_lite::{future, prelude::*}; |
| 18 | + use std::io; |
| 19 | + use tempfile::tempdir; |
| 20 | + |
| 21 | + // n.b.: notgull: uds_windows does not support I/O safety uet, hence the wrapper types |
| 22 | + |
| 23 | + struct UnixListener(uds_windows::UnixListener); |
| 24 | + |
| 25 | + impl From<uds_windows::UnixListener> for UnixListener { |
| 26 | + fn from(ul: uds_windows::UnixListener) -> Self { |
| 27 | + Self(ul) |
| 28 | + } |
| 29 | + } |
| 30 | + |
| 31 | + impl Deref for UnixListener { |
| 32 | + type Target = uds_windows::UnixListener; |
| 33 | + |
| 34 | + fn deref(&self) -> &uds_windows::UnixListener { |
| 35 | + &self.0 |
| 36 | + } |
| 37 | + } |
| 38 | + |
| 39 | + impl AsSocket for UnixListener { |
| 40 | + fn as_socket(&self) -> BorrowedSocket<'_> { |
| 41 | + unsafe { BorrowedSocket::borrow_raw(self.as_raw_socket()) } |
| 42 | + } |
| 43 | + } |
| 44 | + |
| 45 | + struct UnixStream(uds_windows::UnixStream); |
| 46 | + |
| 47 | + impl From<uds_windows::UnixStream> for UnixStream { |
| 48 | + fn from(ul: uds_windows::UnixStream) -> Self { |
| 49 | + Self(ul) |
| 50 | + } |
| 51 | + } |
| 52 | + |
| 53 | + impl Deref for UnixStream { |
| 54 | + type Target = uds_windows::UnixStream; |
| 55 | + |
| 56 | + fn deref(&self) -> &uds_windows::UnixStream { |
| 57 | + &self.0 |
| 58 | + } |
| 59 | + } |
| 60 | + |
| 61 | + impl AsSocket for UnixStream { |
| 62 | + fn as_socket(&self) -> BorrowedSocket<'_> { |
| 63 | + unsafe { BorrowedSocket::borrow_raw(self.as_raw_socket()) } |
| 64 | + } |
| 65 | + } |
| 66 | + |
| 67 | + impl io::Read for UnixStream { |
| 68 | + fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { |
| 69 | + io::Read::read(&mut self.0, buf) |
| 70 | + } |
| 71 | + } |
| 72 | + |
| 73 | + impl io::Write for UnixStream { |
| 74 | + fn write(&mut self, buf: &[u8]) -> io::Result<usize> { |
| 75 | + io::Write::write(&mut self.0, buf) |
| 76 | + } |
| 77 | + |
| 78 | + fn flush(&mut self) -> io::Result<()> { |
| 79 | + io::Write::flush(&mut self.0) |
| 80 | + } |
| 81 | + } |
| 82 | + |
| 83 | + unsafe impl async_io::IoSafe for UnixStream {} |
| 84 | + |
| 85 | + async fn client(addr: PathBuf) -> io::Result<()> { |
| 86 | + // Connect to the address. |
| 87 | + let stream = Async::new(UnixStream::from(uds_windows::UnixStream::connect(addr)?))?; |
| 88 | + println!("Connected to {:?}", stream.get_ref().peer_addr()?); |
| 89 | + |
| 90 | + // Pipe the stream to stdout. |
| 91 | + let mut stdout = Unblock::new(std::io::stdout()); |
| 92 | + futures_lite::io::copy(stream, &mut stdout).await?; |
| 93 | + Ok(()) |
| 94 | + } |
| 95 | + |
| 96 | + let dir = tempdir()?; |
| 97 | + let path = dir.path().join("socket"); |
| 98 | + |
| 99 | + future::block_on(async { |
| 100 | + // Create a listener. |
| 101 | + let listener = Async::new(UnixListener::from(uds_windows::UnixListener::bind(&path)?))?; |
| 102 | + println!("Listening on {:?}", listener.get_ref().local_addr()?); |
| 103 | + |
| 104 | + future::try_zip( |
| 105 | + async { |
| 106 | + // Accept the client. |
| 107 | + let (stream, _) = listener.read_with(|l| l.accept()).await?; |
| 108 | + println!("Accepted a client"); |
| 109 | + |
| 110 | + // Send a message, drop the stream, and wait for the client. |
| 111 | + Async::new(UnixStream::from(stream))? |
| 112 | + .write_all(b"Hello!\n") |
| 113 | + .await?; |
| 114 | + Ok(()) |
| 115 | + }, |
| 116 | + client(path), |
| 117 | + ) |
| 118 | + .await?; |
| 119 | + |
| 120 | + Ok(()) |
| 121 | + }) |
| 122 | +} |
| 123 | + |
| 124 | +#[cfg(not(windows))] |
9 | 125 | fn main() {
|
10 |
| - println!("TODO: Restore this example from git once uds_windows implements I/O safety"); |
| 126 | + println!("This example works only on Windows!"); |
11 | 127 | }
|
0 commit comments