std/os/unix/net/stream.rs
1cfg_select! {
2 any(
3 target_os = "linux", target_os = "android",
4 target_os = "hurd",
5 target_os = "dragonfly", target_os = "freebsd",
6 target_os = "openbsd", target_os = "netbsd",
7 target_os = "solaris", target_os = "illumos",
8 target_os = "haiku", target_os = "nto",
9 target_os = "cygwin",
10 ) => {
11 use libc::MSG_NOSIGNAL;
12 }
13 _ => {
14 const MSG_NOSIGNAL: core::ffi::c_int = 0x0;
15 }
16}
17
18use super::{SocketAddr, sockaddr_un};
19#[cfg(any(doc, target_os = "android", target_os = "linux", target_os = "cygwin"))]
20use super::{SocketAncillary, recv_vectored_with_ancillary_from, send_vectored_with_ancillary_to};
21#[cfg(any(
22 target_os = "android",
23 target_os = "linux",
24 target_os = "dragonfly",
25 target_os = "freebsd",
26 target_os = "netbsd",
27 target_os = "openbsd",
28 target_os = "nto",
29 target_vendor = "apple",
30 target_os = "cygwin"
31))]
32use super::{UCred, peer_cred};
33use crate::fmt;
34use crate::io::{self, IoSlice, IoSliceMut};
35use crate::net::Shutdown;
36use crate::os::unix::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, OwnedFd, RawFd};
37use crate::path::Path;
38use crate::sys::net::Socket;
39use crate::sys::{AsInner, FromInner, cvt};
40use crate::time::Duration;
41
42/// A Unix stream socket.
43///
44/// # Examples
45///
46/// ```no_run
47/// use std::os::unix::net::UnixStream;
48/// use std::io::prelude::*;
49///
50/// fn main() -> std::io::Result<()> {
51/// let mut stream = UnixStream::connect("/path/to/my/socket")?;
52/// stream.write_all(b"hello world")?;
53/// let mut response = String::new();
54/// stream.read_to_string(&mut response)?;
55/// println!("{response}");
56/// Ok(())
57/// }
58/// ```
59///
60/// # `SOCK_CLOEXEC`
61///
62/// On platforms that support it, we pass the close-on-exec flag to atomically create the socket and
63/// set it as CLOEXEC. On Linux, this was added in 2.6.27. See [`socket(2)`] for more information.
64///
65/// [`socket(2)`]: https://www.man7.org/linux/man-pages/man2/socket.2.html#:~:text=SOCK_CLOEXEC
66///
67/// # `SIGPIPE`
68///
69/// Writes to the underlying socket in `SOCK_STREAM` mode are made with `MSG_NOSIGNAL` flag.
70/// This suppresses the emission of the `SIGPIPE` signal when writing to disconnected socket.
71/// In some cases getting a `SIGPIPE` would trigger process termination.
72#[stable(feature = "unix_socket", since = "1.10.0")]
73pub struct UnixStream(pub(super) Socket);
74
75#[stable(feature = "unix_socket", since = "1.10.0")]
76impl fmt::Debug for UnixStream {
77 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
78 let mut builder = fmt.debug_struct("UnixStream");
79 builder.field("fd", self.0.as_inner());
80 if let Ok(addr) = self.local_addr() {
81 builder.field("local", &addr);
82 }
83 if let Ok(addr) = self.peer_addr() {
84 builder.field("peer", &addr);
85 }
86 builder.finish()
87 }
88}
89
90impl UnixStream {
91 /// Connects to the socket named by `path`.
92 ///
93 /// # Examples
94 ///
95 /// ```no_run
96 /// use std::os::unix::net::UnixStream;
97 ///
98 /// let socket = match UnixStream::connect("/tmp/sock") {
99 /// Ok(sock) => sock,
100 /// Err(e) => {
101 /// println!("Couldn't connect: {e:?}");
102 /// return
103 /// }
104 /// };
105 /// ```
106 #[stable(feature = "unix_socket", since = "1.10.0")]
107 pub fn connect<P: AsRef<Path>>(path: P) -> io::Result<UnixStream> {
108 unsafe {
109 let inner = Socket::new(libc::AF_UNIX, libc::SOCK_STREAM)?;
110 let (addr, len) = sockaddr_un(path.as_ref())?;
111
112 cvt(libc::connect(inner.as_raw_fd(), (&raw const addr) as *const _, len))?;
113 Ok(UnixStream(inner))
114 }
115 }
116
117 /// Connects to the socket specified by [`address`].
118 ///
119 /// [`address`]: crate::os::unix::net::SocketAddr
120 ///
121 /// # Examples
122 ///
123 /// ```no_run
124 /// use std::os::unix::net::{UnixListener, UnixStream};
125 ///
126 /// fn main() -> std::io::Result<()> {
127 /// let listener = UnixListener::bind("/path/to/the/socket")?;
128 /// let addr = listener.local_addr()?;
129 ///
130 /// let sock = match UnixStream::connect_addr(&addr) {
131 /// Ok(sock) => sock,
132 /// Err(e) => {
133 /// println!("Couldn't connect: {e:?}");
134 /// return Err(e)
135 /// }
136 /// };
137 /// Ok(())
138 /// }
139 /// ````
140 #[stable(feature = "unix_socket_abstract", since = "1.70.0")]
141 pub fn connect_addr(socket_addr: &SocketAddr) -> io::Result<UnixStream> {
142 unsafe {
143 let inner = Socket::new(libc::AF_UNIX, libc::SOCK_STREAM)?;
144 cvt(libc::connect(
145 inner.as_raw_fd(),
146 (&raw const socket_addr.addr) as *const _,
147 socket_addr.len,
148 ))?;
149 Ok(UnixStream(inner))
150 }
151 }
152
153 /// Creates an unnamed pair of connected sockets.
154 ///
155 /// Returns two `UnixStream`s which are connected to each other.
156 ///
157 /// # Examples
158 ///
159 /// ```no_run
160 /// use std::os::unix::net::UnixStream;
161 ///
162 /// let (sock1, sock2) = match UnixStream::pair() {
163 /// Ok((sock1, sock2)) => (sock1, sock2),
164 /// Err(e) => {
165 /// println!("Couldn't create a pair of sockets: {e:?}");
166 /// return
167 /// }
168 /// };
169 /// ```
170 #[stable(feature = "unix_socket", since = "1.10.0")]
171 pub fn pair() -> io::Result<(UnixStream, UnixStream)> {
172 let (i1, i2) = Socket::new_pair(libc::AF_UNIX, libc::SOCK_STREAM)?;
173 Ok((UnixStream(i1), UnixStream(i2)))
174 }
175
176 /// Creates a new independently owned handle to the underlying socket.
177 ///
178 /// The returned `UnixStream` is a reference to the same stream that this
179 /// object references. Both handles will read and write the same stream of
180 /// data, and options set on one stream will be propagated to the other
181 /// stream.
182 ///
183 /// # Examples
184 ///
185 /// ```no_run
186 /// use std::os::unix::net::UnixStream;
187 ///
188 /// fn main() -> std::io::Result<()> {
189 /// let socket = UnixStream::connect("/tmp/sock")?;
190 /// let sock_copy = socket.try_clone().expect("Couldn't clone socket");
191 /// Ok(())
192 /// }
193 /// ```
194 #[stable(feature = "unix_socket", since = "1.10.0")]
195 pub fn try_clone(&self) -> io::Result<UnixStream> {
196 self.0.duplicate().map(UnixStream)
197 }
198
199 /// Returns the socket address of the local half of this connection.
200 ///
201 /// # Examples
202 ///
203 /// ```no_run
204 /// use std::os::unix::net::UnixStream;
205 ///
206 /// fn main() -> std::io::Result<()> {
207 /// let socket = UnixStream::connect("/tmp/sock")?;
208 /// let addr = socket.local_addr().expect("Couldn't get local address");
209 /// Ok(())
210 /// }
211 /// ```
212 #[stable(feature = "unix_socket", since = "1.10.0")]
213 pub fn local_addr(&self) -> io::Result<SocketAddr> {
214 SocketAddr::new(|addr, len| unsafe { libc::getsockname(self.as_raw_fd(), addr, len) })
215 }
216
217 /// Returns the socket address of the remote half of this connection.
218 ///
219 /// # Examples
220 ///
221 /// ```no_run
222 /// use std::os::unix::net::UnixStream;
223 ///
224 /// fn main() -> std::io::Result<()> {
225 /// let socket = UnixStream::connect("/tmp/sock")?;
226 /// let addr = socket.peer_addr().expect("Couldn't get peer address");
227 /// Ok(())
228 /// }
229 /// ```
230 #[stable(feature = "unix_socket", since = "1.10.0")]
231 pub fn peer_addr(&self) -> io::Result<SocketAddr> {
232 SocketAddr::new(|addr, len| unsafe { libc::getpeername(self.as_raw_fd(), addr, len) })
233 }
234
235 /// Gets the peer credentials for this Unix domain socket.
236 ///
237 /// # Examples
238 ///
239 /// ```no_run
240 /// #![feature(peer_credentials_unix_socket)]
241 /// use std::os::unix::net::UnixStream;
242 ///
243 /// fn main() -> std::io::Result<()> {
244 /// let socket = UnixStream::connect("/tmp/sock")?;
245 /// let peer_cred = socket.peer_cred().expect("Couldn't get peer credentials");
246 /// Ok(())
247 /// }
248 /// ```
249 #[unstable(feature = "peer_credentials_unix_socket", issue = "42839")]
250 #[cfg(any(
251 target_os = "android",
252 target_os = "linux",
253 target_os = "dragonfly",
254 target_os = "freebsd",
255 target_os = "netbsd",
256 target_os = "openbsd",
257 target_os = "nto",
258 target_vendor = "apple",
259 target_os = "cygwin"
260 ))]
261 pub fn peer_cred(&self) -> io::Result<UCred> {
262 peer_cred(self)
263 }
264
265 /// Sets the read timeout for the socket.
266 ///
267 /// If the provided value is [`None`], then [`read`] calls will block
268 /// indefinitely. An [`Err`] is returned if the zero [`Duration`] is passed to this
269 /// method.
270 ///
271 /// [`read`]: io::Read::read
272 ///
273 /// # Examples
274 ///
275 /// ```no_run
276 /// use std::os::unix::net::UnixStream;
277 /// use std::time::Duration;
278 ///
279 /// fn main() -> std::io::Result<()> {
280 /// let socket = UnixStream::connect("/tmp/sock")?;
281 /// socket.set_read_timeout(Some(Duration::new(1, 0))).expect("Couldn't set read timeout");
282 /// Ok(())
283 /// }
284 /// ```
285 ///
286 /// An [`Err`] is returned if the zero [`Duration`] is passed to this
287 /// method:
288 ///
289 /// ```no_run
290 /// use std::io;
291 /// use std::os::unix::net::UnixStream;
292 /// use std::time::Duration;
293 ///
294 /// fn main() -> std::io::Result<()> {
295 /// let socket = UnixStream::connect("/tmp/sock")?;
296 /// let result = socket.set_read_timeout(Some(Duration::new(0, 0)));
297 /// let err = result.unwrap_err();
298 /// assert_eq!(err.kind(), io::ErrorKind::InvalidInput);
299 /// Ok(())
300 /// }
301 /// ```
302 #[stable(feature = "unix_socket", since = "1.10.0")]
303 pub fn set_read_timeout(&self, timeout: Option<Duration>) -> io::Result<()> {
304 self.0.set_timeout(timeout, libc::SO_RCVTIMEO)
305 }
306
307 /// Sets the write timeout for the socket.
308 ///
309 /// If the provided value is [`None`], then [`write`] calls will block
310 /// indefinitely. An [`Err`] is returned if the zero [`Duration`] is
311 /// passed to this method.
312 ///
313 /// [`read`]: io::Read::read
314 ///
315 /// # Examples
316 ///
317 /// ```no_run
318 /// use std::os::unix::net::UnixStream;
319 /// use std::time::Duration;
320 ///
321 /// fn main() -> std::io::Result<()> {
322 /// let socket = UnixStream::connect("/tmp/sock")?;
323 /// socket.set_write_timeout(Some(Duration::new(1, 0)))
324 /// .expect("Couldn't set write timeout");
325 /// Ok(())
326 /// }
327 /// ```
328 ///
329 /// An [`Err`] is returned if the zero [`Duration`] is passed to this
330 /// method:
331 ///
332 /// ```no_run
333 /// use std::io;
334 /// use std::os::unix::net::UnixStream;
335 /// use std::time::Duration;
336 ///
337 /// fn main() -> std::io::Result<()> {
338 /// let socket = UnixStream::connect("/tmp/sock")?;
339 /// let result = socket.set_write_timeout(Some(Duration::new(0, 0)));
340 /// let err = result.unwrap_err();
341 /// assert_eq!(err.kind(), io::ErrorKind::InvalidInput);
342 /// Ok(())
343 /// }
344 /// ```
345 #[stable(feature = "unix_socket", since = "1.10.0")]
346 pub fn set_write_timeout(&self, timeout: Option<Duration>) -> io::Result<()> {
347 self.0.set_timeout(timeout, libc::SO_SNDTIMEO)
348 }
349
350 /// Returns the read timeout of this socket.
351 ///
352 /// # Examples
353 ///
354 /// ```no_run
355 /// use std::os::unix::net::UnixStream;
356 /// use std::time::Duration;
357 ///
358 /// fn main() -> std::io::Result<()> {
359 /// let socket = UnixStream::connect("/tmp/sock")?;
360 /// socket.set_read_timeout(Some(Duration::new(1, 0))).expect("Couldn't set read timeout");
361 /// assert_eq!(socket.read_timeout()?, Some(Duration::new(1, 0)));
362 /// Ok(())
363 /// }
364 /// ```
365 #[stable(feature = "unix_socket", since = "1.10.0")]
366 pub fn read_timeout(&self) -> io::Result<Option<Duration>> {
367 self.0.timeout(libc::SO_RCVTIMEO)
368 }
369
370 /// Returns the write timeout of this socket.
371 ///
372 /// # Examples
373 ///
374 /// ```no_run
375 /// use std::os::unix::net::UnixStream;
376 /// use std::time::Duration;
377 ///
378 /// fn main() -> std::io::Result<()> {
379 /// let socket = UnixStream::connect("/tmp/sock")?;
380 /// socket.set_write_timeout(Some(Duration::new(1, 0)))
381 /// .expect("Couldn't set write timeout");
382 /// assert_eq!(socket.write_timeout()?, Some(Duration::new(1, 0)));
383 /// Ok(())
384 /// }
385 /// ```
386 #[stable(feature = "unix_socket", since = "1.10.0")]
387 pub fn write_timeout(&self) -> io::Result<Option<Duration>> {
388 self.0.timeout(libc::SO_SNDTIMEO)
389 }
390
391 /// Moves the socket into or out of nonblocking mode.
392 ///
393 /// # Examples
394 ///
395 /// ```no_run
396 /// use std::os::unix::net::UnixStream;
397 ///
398 /// fn main() -> std::io::Result<()> {
399 /// let socket = UnixStream::connect("/tmp/sock")?;
400 /// socket.set_nonblocking(true).expect("Couldn't set nonblocking");
401 /// Ok(())
402 /// }
403 /// ```
404 #[stable(feature = "unix_socket", since = "1.10.0")]
405 pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
406 self.0.set_nonblocking(nonblocking)
407 }
408
409 /// Set the id of the socket for network filtering purpose
410 ///
411 #[cfg_attr(
412 any(target_os = "linux", target_os = "freebsd", target_os = "openbsd"),
413 doc = "```no_run"
414 )]
415 #[cfg_attr(
416 not(any(target_os = "linux", target_os = "freebsd", target_os = "openbsd")),
417 doc = "```ignore"
418 )]
419 /// #![feature(unix_set_mark)]
420 /// use std::os::unix::net::UnixStream;
421 ///
422 /// fn main() -> std::io::Result<()> {
423 /// let sock = UnixStream::connect("/tmp/sock")?;
424 /// sock.set_mark(32)?;
425 /// Ok(())
426 /// }
427 /// ```
428 #[cfg(any(doc, target_os = "linux", target_os = "freebsd", target_os = "openbsd",))]
429 #[unstable(feature = "unix_set_mark", issue = "96467")]
430 pub fn set_mark(&self, mark: u32) -> io::Result<()> {
431 self.0.set_mark(mark)
432 }
433
434 /// Returns the value of the `SO_ERROR` option.
435 ///
436 /// # Examples
437 ///
438 /// ```no_run
439 /// use std::os::unix::net::UnixStream;
440 ///
441 /// fn main() -> std::io::Result<()> {
442 /// let socket = UnixStream::connect("/tmp/sock")?;
443 /// if let Ok(Some(err)) = socket.take_error() {
444 /// println!("Got error: {err:?}");
445 /// }
446 /// Ok(())
447 /// }
448 /// ```
449 ///
450 /// # Platform specific
451 /// On Redox this always returns `None`.
452 #[stable(feature = "unix_socket", since = "1.10.0")]
453 pub fn take_error(&self) -> io::Result<Option<io::Error>> {
454 self.0.take_error()
455 }
456
457 /// Shuts down the read, write, or both halves of this connection.
458 ///
459 /// This function will cause all pending and future I/O calls on the
460 /// specified portions to immediately return with an appropriate value
461 /// (see the documentation of [`Shutdown`]).
462 ///
463 /// # Examples
464 ///
465 /// ```no_run
466 /// use std::os::unix::net::UnixStream;
467 /// use std::net::Shutdown;
468 ///
469 /// fn main() -> std::io::Result<()> {
470 /// let socket = UnixStream::connect("/tmp/sock")?;
471 /// socket.shutdown(Shutdown::Both).expect("shutdown function failed");
472 /// Ok(())
473 /// }
474 /// ```
475 #[stable(feature = "unix_socket", since = "1.10.0")]
476 pub fn shutdown(&self, how: Shutdown) -> io::Result<()> {
477 self.0.shutdown(how)
478 }
479
480 /// Receives data on the socket from the remote address to which it is
481 /// connected, without removing that data from the queue. On success,
482 /// returns the number of bytes peeked.
483 ///
484 /// Successive calls return the same data. This is accomplished by passing
485 /// `MSG_PEEK` as a flag to the underlying `recv` system call.
486 ///
487 /// # Examples
488 ///
489 /// ```no_run
490 /// #![feature(unix_socket_peek)]
491 ///
492 /// use std::os::unix::net::UnixStream;
493 ///
494 /// fn main() -> std::io::Result<()> {
495 /// let socket = UnixStream::connect("/tmp/sock")?;
496 /// let mut buf = [0; 10];
497 /// let len = socket.peek(&mut buf).expect("peek failed");
498 /// Ok(())
499 /// }
500 /// ```
501 #[unstable(feature = "unix_socket_peek", issue = "76923")]
502 pub fn peek(&self, buf: &mut [u8]) -> io::Result<usize> {
503 self.0.peek(buf)
504 }
505
506 /// Receives data and ancillary data from socket.
507 ///
508 /// On success, returns the number of bytes read.
509 ///
510 /// # Examples
511 ///
512 #[cfg_attr(
513 any(target_os = "android", target_os = "linux", target_os = "cygwin"),
514 doc = "```no_run"
515 )]
516 #[cfg_attr(
517 not(any(target_os = "android", target_os = "linux", target_os = "cygwin")),
518 doc = "```ignore"
519 )]
520 /// #![feature(unix_socket_ancillary_data)]
521 /// use std::os::unix::net::{UnixStream, SocketAncillary, AncillaryData};
522 /// use std::io::IoSliceMut;
523 ///
524 /// fn main() -> std::io::Result<()> {
525 /// let socket = UnixStream::connect("/tmp/sock")?;
526 /// let mut buf1 = [1; 8];
527 /// let mut buf2 = [2; 16];
528 /// let mut buf3 = [3; 8];
529 /// let mut bufs = &mut [
530 /// IoSliceMut::new(&mut buf1),
531 /// IoSliceMut::new(&mut buf2),
532 /// IoSliceMut::new(&mut buf3),
533 /// ][..];
534 /// let mut fds = [0; 8];
535 /// let mut ancillary_buffer = [0; 128];
536 /// let mut ancillary = SocketAncillary::new(&mut ancillary_buffer[..]);
537 /// let size = socket.recv_vectored_with_ancillary(bufs, &mut ancillary)?;
538 /// println!("received {size}");
539 /// for ancillary_result in ancillary.messages() {
540 /// if let AncillaryData::ScmRights(scm_rights) = ancillary_result.unwrap() {
541 /// for fd in scm_rights {
542 /// println!("receive file descriptor: {fd}");
543 /// }
544 /// }
545 /// }
546 /// Ok(())
547 /// }
548 /// ```
549 #[cfg(any(doc, target_os = "android", target_os = "linux", target_os = "cygwin"))]
550 #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")]
551 pub fn recv_vectored_with_ancillary(
552 &self,
553 bufs: &mut [IoSliceMut<'_>],
554 ancillary: &mut SocketAncillary<'_>,
555 ) -> io::Result<usize> {
556 let (count, _, _) = recv_vectored_with_ancillary_from(&self.0, bufs, ancillary)?;
557
558 Ok(count)
559 }
560
561 /// Sends data and ancillary data on the socket.
562 ///
563 /// On success, returns the number of bytes written.
564 ///
565 /// # Examples
566 ///
567 #[cfg_attr(
568 any(target_os = "android", target_os = "linux", target_os = "cygwin"),
569 doc = "```no_run"
570 )]
571 #[cfg_attr(
572 not(any(target_os = "android", target_os = "linux", target_os = "cygwin")),
573 doc = "```ignore"
574 )]
575 /// #![feature(unix_socket_ancillary_data)]
576 /// use std::os::unix::net::{UnixStream, SocketAncillary};
577 /// use std::io::IoSlice;
578 ///
579 /// fn main() -> std::io::Result<()> {
580 /// let socket = UnixStream::connect("/tmp/sock")?;
581 /// let buf1 = [1; 8];
582 /// let buf2 = [2; 16];
583 /// let buf3 = [3; 8];
584 /// let bufs = &[
585 /// IoSlice::new(&buf1),
586 /// IoSlice::new(&buf2),
587 /// IoSlice::new(&buf3),
588 /// ][..];
589 /// let fds = [0, 1, 2];
590 /// let mut ancillary_buffer = [0; 128];
591 /// let mut ancillary = SocketAncillary::new(&mut ancillary_buffer[..]);
592 /// ancillary.add_fds(&fds[..]);
593 /// socket.send_vectored_with_ancillary(bufs, &mut ancillary)
594 /// .expect("send_vectored_with_ancillary function failed");
595 /// Ok(())
596 /// }
597 /// ```
598 #[cfg(any(doc, target_os = "android", target_os = "linux", target_os = "cygwin"))]
599 #[unstable(feature = "unix_socket_ancillary_data", issue = "76915")]
600 pub fn send_vectored_with_ancillary(
601 &self,
602 bufs: &[IoSlice<'_>],
603 ancillary: &mut SocketAncillary<'_>,
604 ) -> io::Result<usize> {
605 send_vectored_with_ancillary_to(&self.0, None, bufs, ancillary)
606 }
607}
608
609#[stable(feature = "unix_socket", since = "1.10.0")]
610impl io::Read for UnixStream {
611 fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
612 io::Read::read(&mut &*self, buf)
613 }
614
615 fn read_buf(&mut self, buf: io::BorrowedCursor<'_, u8>) -> io::Result<()> {
616 io::Read::read_buf(&mut &*self, buf)
617 }
618
619 fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
620 io::Read::read_vectored(&mut &*self, bufs)
621 }
622
623 #[inline]
624 fn is_read_vectored(&self) -> bool {
625 io::Read::is_read_vectored(&&*self)
626 }
627}
628
629#[stable(feature = "unix_socket", since = "1.10.0")]
630impl<'a> io::Read for &'a UnixStream {
631 fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
632 self.0.read(buf)
633 }
634
635 fn read_buf(&mut self, buf: io::BorrowedCursor<'_, u8>) -> io::Result<()> {
636 self.0.read_buf(buf)
637 }
638
639 fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
640 self.0.read_vectored(bufs)
641 }
642
643 #[inline]
644 fn is_read_vectored(&self) -> bool {
645 self.0.is_read_vectored()
646 }
647}
648
649#[stable(feature = "unix_socket", since = "1.10.0")]
650impl io::Write for UnixStream {
651 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
652 io::Write::write(&mut &*self, buf)
653 }
654
655 fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
656 io::Write::write_vectored(&mut &*self, bufs)
657 }
658
659 #[inline]
660 fn is_write_vectored(&self) -> bool {
661 io::Write::is_write_vectored(&&*self)
662 }
663
664 fn flush(&mut self) -> io::Result<()> {
665 io::Write::flush(&mut &*self)
666 }
667}
668
669#[stable(feature = "unix_socket", since = "1.10.0")]
670impl<'a> io::Write for &'a UnixStream {
671 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
672 self.0.send_with_flags(buf, MSG_NOSIGNAL)
673 }
674
675 fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
676 self.0.write_vectored(bufs)
677 }
678
679 #[inline]
680 fn is_write_vectored(&self) -> bool {
681 self.0.is_write_vectored()
682 }
683
684 #[inline]
685 fn flush(&mut self) -> io::Result<()> {
686 Ok(())
687 }
688}
689
690#[stable(feature = "unix_socket", since = "1.10.0")]
691impl AsRawFd for UnixStream {
692 #[inline]
693 fn as_raw_fd(&self) -> RawFd {
694 self.0.as_raw_fd()
695 }
696}
697
698#[stable(feature = "unix_socket", since = "1.10.0")]
699impl FromRawFd for UnixStream {
700 #[inline]
701 unsafe fn from_raw_fd(fd: RawFd) -> UnixStream {
702 UnixStream(Socket::from_inner(FromInner::from_inner(OwnedFd::from_raw_fd(fd))))
703 }
704}
705
706#[stable(feature = "unix_socket", since = "1.10.0")]
707impl IntoRawFd for UnixStream {
708 #[inline]
709 fn into_raw_fd(self) -> RawFd {
710 self.0.into_raw_fd()
711 }
712}
713
714#[stable(feature = "io_safety", since = "1.63.0")]
715impl AsFd for UnixStream {
716 #[inline]
717 fn as_fd(&self) -> BorrowedFd<'_> {
718 self.0.as_fd()
719 }
720}
721
722#[stable(feature = "io_safety", since = "1.63.0")]
723impl From<UnixStream> for OwnedFd {
724 /// Takes ownership of a [`UnixStream`]'s socket file descriptor.
725 #[inline]
726 fn from(unix_stream: UnixStream) -> OwnedFd {
727 unsafe { OwnedFd::from_raw_fd(unix_stream.into_raw_fd()) }
728 }
729}
730
731#[stable(feature = "io_safety", since = "1.63.0")]
732impl From<OwnedFd> for UnixStream {
733 #[inline]
734 fn from(owned: OwnedFd) -> Self {
735 unsafe { Self::from_raw_fd(owned.into_raw_fd()) }
736 }
737}
738
739impl AsInner<Socket> for UnixStream {
740 #[inline]
741 fn as_inner(&self) -> &Socket {
742 &self.0
743 }
744}