1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
//! Local sockets, a socket-like IPC primitive in which clients access a server through a
//! filesystem path or an identifier inside a special namespace, with each client having a
//! private connection to the server.
//!
//! ## Implementations and dispatch
//! Local sockets are not a real IPC primitive implemented by the OS, but rather a construct of
//! Interprocess that is implemented in terms of an underlying IPC primitive. Different IPC
//! primitives are available on different platforms and have different capabilities and
//! limitations. As such, the types representing local sockets that you can find in this
//! module – [`Listener`], [`Stream`], [`RecvHalf`], [`SendHalf`] – are really enums in the style
//! of `enum_dispatch` that contain variants for all the different implementations of local
//! sockets that are available, and the types that they dispatch between are talked to via the
//! corresponding [`Listener`](traits::Listener), [`Stream`](traits::Stream)
//! [`RecvHalf`](traits::RecvHalf), [`SendHalf`](traits::SendHalf) traits that you can find in the
//! [`traits`] module. (Note that this dispatch is currently zero-cost on all platforms, as there
//! is only one underlying local socket implementation per platform, with Windows only using named
//! pipe based local sockets and Unix only using Unix-domain socket based local sockets, but this
//! may change in the future with the introduction of support for
//! [the Windows implementation of Unix-domain sockets][udswnd]. Even then, the overhead of this
//! dispatch is insignificant compared to the overhead of making the system calls that perform
//! the actual communication.)
//!
//! [udswnd]: https://devblogs.microsoft.com/commandline/af_unix-comes-to-windows/
//!
//! The [`prelude`] module is there to make it easier to handle all of this complexity without
//! suffering from naming collisions. **`use interprocess::local_socket::prelude::*;` is the
//! recommended way of bringing local sockets into scope.**
//!
//! ## Stability
//! Since interprocess communication cannot happen without agreement on a protocol between two or
//! more processes, the mapping of local sockets to underlying primitives is stable and
//! predictable. **The IPC primitive selected depends only on the current platform and the
//! [name type](NameType) used.** The mapping is trivial unless noted otherwise (in particular,
//! Interprocess never inserts its own message framing or any other type of metadata into the
//! stream – the bytes you write are the exact bytes that come out the other end), which means
//! that the portable API of local sockets is suitable for communicating with programs that do
//! not use Interprocess themselves, including programs not written in Rust. All you need to do
//! is use the correct name type for every platform.
//!
//! ## Raw handle and file descriptor access
//! The enum dispatchers purposely omit implementations of `{As,Into,From}Raw{Handle,Fd}`,
//! `As{Handle,Fd}`, `From<Owned{HandleFd}>` and `Into<Owned{Handle,Fd}>`. To access those trait
//! implementations on the underlying implementation types, you need to match on the enum. For
//! instance:
//! ```no_run
//! # #[cfg(unix)]
//! use {interprocess::local_socket::prelude::*, std::os::unix::prelude::*};
//! # #[cfg(unix)] fn hi(fd: OwnedFd, fd2: OwnedFd) {
//!
//! // Creating a stream from a file descriptor
//! let stream = LocalSocketStream::UdSocket(fd.into());
//! # let _ = stream;
//!
//! // Consuming a stream to get its file descriptor
//! let fd = match stream {
//! LocalSocketStream::UdSocket(s) => OwnedFd::from(s),
//! };
//! # let _ = fd;
//!
//! # let stream = LocalSocketStream::UdSocket(fd2.into());
//! // Accessing a stream's file descriptor without taking ownership
//! let stream_impl = match &stream {
//! LocalSocketStream::UdSocket(s) => s,
//! };
//! let fd = stream_impl.as_fd();
//! # let _ = fd;
//!
//! // Listener, RecvHalf, and SendHalf work analogously.
//! // Works just the same on Windows under the replacement of Fd with Handle.
//! # }
//! ```
/// Traits representing the interface of local sockets.
pub use ;
/// Re-exports of [traits] done in a way that doesn't pollute the scope, as well as of the
/// enum-dispatch types with their names prefixed with `LocalSocket`.
/// Asynchronous local sockets which work with the Tokio runtime and event loop.
///
/// The Tokio integration allows the local socket streams and listeners to be notified by the OS
/// kernel whenever they're ready to be received from of sent to, instead of requiring you to
/// spawn threads just to put them in a wait state of blocking on the I/O.
///
/// Everything said in the [documentation for sync local sockets](crate::local_socket) applies to
/// the Tokio versions of the corresponding items as well. Please read it before using Tokio-based
/// local sockets.
///
/// Types from this module will *not* work with other async runtimes, such as `async-std` or `smol`,
/// since the Tokio types' methods will panic whenever they're called outside of a Tokio runtime
/// context. Open an issue if you'd like to see other runtimes supported as well.