interprocess_docfix/os/unix/udsocket/tokio/stream/
write_half.rs

1#[cfg(uds_supported)]
2use super::c_wrappers;
3use super::{OwnedReadHalf, ReuniteError, UdStream};
4use crate::os::unix::imports::*;
5use std::{
6    io,
7    net::Shutdown,
8    pin::Pin,
9    task::{Context, Poll},
10};
11
12/// Borrowed write half of a [`UdStream`](super::UdStream), created by [`.split()`](super::UdStream::split).
13#[derive(Debug)]
14pub struct BorrowedWriteHalf<'a>(pub(super) TokioUdStreamWriteHalf<'a>);
15
16impl<'a> BorrowedWriteHalf<'a> {
17    /// Fetches the credentials of the other end of the connection without using ancillary data. The returned structure contains the process identifier, user identifier and group identifier of the peer.
18    #[cfg(any(doc, uds_peercred))]
19    #[cfg_attr( // uds_peercred template
20        feature = "doc_cfg",
21        doc(cfg(any(
22            all(
23                target_os = "linux",
24                any(
25                    target_env = "gnu",
26                    target_env = "musl",
27                    target_env = "musleabi",
28                    target_env = "musleabihf"
29                )
30            ),
31            target_os = "emscripten",
32            target_os = "redox",
33            target_os = "haiku"
34        )))
35    )]
36    pub fn get_peer_credentials(&self) -> io::Result<ucred> {
37        c_wrappers::get_peer_ucred(self.as_stream_raw_fd().as_ref())
38    }
39    /// Shuts down the write half.
40    ///
41    /// Attempting to call this method multiple times may return `Ok(())` every time or it may return an error the second time it is called, depending on the platform. You must either avoid using the same value twice or ignore the error entirely.
42    pub fn shutdown(&self) -> io::Result<()> {
43        c_wrappers::shutdown(self.as_stream_raw_fd().as_ref(), Shutdown::Write)
44    }
45
46    /// Returns the underlying file descriptor. Note that this isn't a file descriptor for the write half specifically, but rather for the whole stream, so this isn't exposed as a struct method.
47    fn as_stream_raw_fd(&self) -> c_int {
48        let stream: &TokioUdStream = self.0.as_ref();
49        stream.as_raw_fd()
50    }
51
52    fn pinproject(self: Pin<&mut Self>) -> Pin<&mut TokioUdStreamWriteHalf<'a>> {
53        Pin::new(&mut self.get_mut().0)
54    }
55
56    tokio_wrapper_conversion_methods!(tokio_norawfd TokioUdStreamWriteHalf<'a>);
57}
58
59#[cfg(feature = "tokio_support")]
60impl TokioAsyncWrite for BorrowedWriteHalf<'_> {
61    fn poll_write(
62        self: Pin<&mut Self>,
63        cx: &mut Context<'_>,
64        buf: &[u8],
65    ) -> Poll<Result<usize, io::Error>> {
66        self.pinproject().poll_write(cx, buf)
67    }
68    fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), io::Error>> {
69        self.pinproject().poll_flush(cx)
70    }
71    /// Finishes immediately. See the `.shutdown()` method.
72    fn poll_shutdown(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), io::Error>> {
73        self.pinproject().poll_shutdown(cx)
74    }
75}
76#[cfg(feature = "tokio_support")]
77impl FuturesAsyncWrite for BorrowedWriteHalf<'_> {
78    fn poll_write(
79        self: Pin<&mut Self>,
80        cx: &mut Context<'_>,
81        buf: &[u8],
82    ) -> Poll<Result<usize, io::Error>> {
83        self.pinproject().poll_write(cx, buf)
84    }
85    fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), io::Error>> {
86        self.pinproject().poll_flush(cx)
87    }
88    /// Finishes immediately. See the `.shutdown()` method.
89    fn poll_close(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<Result<(), io::Error>> {
90        self.shutdown()?;
91        Poll::Ready(Ok(()))
92    }
93}
94
95tokio_wrapper_trait_impls!(
96    for BorrowedWriteHalf<'a>, tokio_norawfd_lt 'a TokioUdStreamWriteHalf<'a>);
97
98/// Owned write half of a [`UdStream`](super::UdStream), created by [`.into_split()`](super::UdStream::into_split).
99#[derive(Debug)]
100pub struct OwnedWriteHalf(pub(super) TokioUdStreamOwnedWriteHalf);
101impl OwnedWriteHalf {
102    /// Attempts to put two owned halves of a stream back together and recover the original stream. Succeeds only if the two halves originated from the same call to [`.into_split()`](UdStream::into_split).
103    pub fn reunite_with(self, read: OwnedReadHalf) -> Result<UdStream, ReuniteError> {
104        UdStream::reunite(read, self)
105    }
106
107    /// Fetches the credentials of the other end of the connection without using ancillary data. The returned structure contains the process identifier, user identifier and group identifier of the peer.
108    #[cfg(any(doc, uds_peercred))]
109    #[cfg_attr( // uds_peercred template
110        feature = "doc_cfg",
111        doc(cfg(any(
112            all(
113                target_os = "linux",
114                any(
115                    target_env = "gnu",
116                    target_env = "musl",
117                    target_env = "musleabi",
118                    target_env = "musleabihf"
119                )
120            ),
121            target_os = "emscripten",
122            target_os = "redox",
123            target_os = "haiku"
124        )))
125    )]
126    pub fn get_peer_credentials(&self) -> io::Result<ucred> {
127        c_wrappers::get_peer_ucred(self.as_stream_raw_fd().as_ref())
128    }
129
130    /// Shuts down the write half.
131    ///
132    /// Attempting to call this method multiple times may return `Ok(())` every time or it may return an error the second time it is called, depending on the platform. You must either avoid using the same value twice or ignore the error entirely.
133    pub fn shutdown(&self) -> io::Result<()> {
134        c_wrappers::shutdown(self.as_stream_raw_fd().as_ref(), Shutdown::Write)
135    }
136
137    /// Returns the underlying file descriptor. Note that this isn't a file descriptor for the write half specifically, but rather for the whole stream, so this isn't exposed as a struct method.
138    fn as_stream_raw_fd(&self) -> c_int {
139        let stream: &TokioUdStream = self.0.as_ref();
140        stream.as_raw_fd()
141    }
142
143    fn pinproject(self: Pin<&mut Self>) -> Pin<&mut TokioUdStreamOwnedWriteHalf> {
144        Pin::new(&mut self.get_mut().0)
145    }
146
147    tokio_wrapper_conversion_methods!(tokio_norawfd TokioUdStreamOwnedWriteHalf);
148}
149
150#[cfg(feature = "tokio_support")]
151impl TokioAsyncWrite for OwnedWriteHalf {
152    fn poll_write(
153        self: Pin<&mut Self>,
154        cx: &mut Context<'_>,
155        buf: &[u8],
156    ) -> Poll<io::Result<usize>> {
157        self.pinproject().poll_write(cx, buf)
158    }
159
160    fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), io::Error>> {
161        self.pinproject().poll_flush(cx)
162    }
163    /// Finishes immediately. See the `.shutdown()` method.
164    fn poll_shutdown(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<Result<(), io::Error>> {
165        self.shutdown()?;
166        Poll::Ready(Ok(()))
167    }
168}
169#[cfg(feature = "tokio_support")]
170impl FuturesAsyncWrite for OwnedWriteHalf {
171    fn poll_write(
172        self: Pin<&mut Self>,
173        cx: &mut Context<'_>,
174        buf: &[u8],
175    ) -> Poll<io::Result<usize>> {
176        self.pinproject().poll_write(cx, buf)
177    }
178    fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), io::Error>> {
179        self.pinproject().poll_flush(cx)
180    }
181    /// Finishes immediately. See the `.shutdown()` method.
182    fn poll_close(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<Result<(), io::Error>> {
183        self.shutdown()?;
184        Poll::Ready(Ok(()))
185    }
186}
187
188tokio_wrapper_trait_impls!(
189    for OwnedWriteHalf, tokio_norawfd TokioUdStreamOwnedWriteHalf);