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