async_send_fd/lib.rs
1//! **async-send-fd** is a library for sending and receiving Unix file descriptors over async UnixStream connections.
2//! You can either transfer
3//! - [RawFd];
4//! - Tokio [UnixStream](tokio::net::UnixStream) if `tokio` feature enabled;
5//! - or Smol [UnixStream](smol::net::unix::UnixStream) if `smol` feature enabled;
6//!
7//! ## Examles
8//! See [test_smol_stream.rs](https://github.com/alexander-smoktal/async-send-fd/blob/main/tests/test_smol_stream.rs) or
9//! [test_tokio_stream.rs](https://github.com/alexander-smoktal/async-send-fd/blob/main/tests/test_tokio_stream.rs) for code examples.
10//!
11//! ## Creating a Tokio [UnixStream](tokio::net::UnixStream) from [RawFd]
12//! If you make a Tokio [UnixStream](tokio::net::UnixStream) from a raw file descriptor made by an
13//! OS call (e.g. [UnixStream::pair](std::os::unix::net::UnixStream::pair())), you must make it
14//! [set_nonblocking(true)](std::os::unix::net::UnixStream::set_nonblocking()), otherwise receivers scheduler will block
15//! writing into the socket ⚠️
16//!
17//! Smol [UnixStream](smol::net::unix::UnixStream) makes it automatically if created using `UnixStream::from(Async::new(stream))`
18//!
19//! ## Transfering socket pair ownership
20//! Sending a descriptor doesn't close the local copy, which leads to having the socket being
21//! opened by the sender until it shuts down.
22//! If you want socket pair receivers to detect peer shutdown, you have to close local sockets after sending them.
23//!
24//! Use [UnixStream::poll_shutdown()](https://docs.rs/tokio/latest/tokio/net/struct.UnixStream.html#method.poll_shutdown) for Tokio streams, or [UnixStream::shutdown()](smol::net::unix::UnixStream::shutdown) for Smol.
25//!
26//! ## Features
27//! - `tokio` - for Tokio support
28//! - `smol` - for Smol support
29use std::{io::Error, os::unix::io::RawFd};
30
31#[cfg(feature = "tokio")]
32mod tokio_stream;
33#[cfg(feature = "tokio")]
34pub use tokio_stream::{AsyncRecvTokioStream, AsyncSendTokioStream};
35
36#[cfg(feature = "smol")]
37mod smol_stream;
38#[cfg(feature = "smol")]
39pub use smol_stream::{AsyncRecvSmolStream, AsyncSendSmolStream};
40
41/// A trait to send raw file descriptors
42pub trait AsyncSendFd {
43 /// Send RawFd
44 fn send_fd(&self, fd: RawFd) -> impl std::future::Future<Output = Result<(), Error>> + Send;
45}
46
47/// A trait to receive raw file descriptors
48pub trait AsyncRecvFd {
49 /// Receive RawFd
50 fn recv_fd(&self) -> impl std::future::Future<Output = Result<RawFd, Error>> + Send;
51}