]> git.lizzy.rs Git - rust.git/blob - src/libstd/sys/redox/ext/net.rs
Auto merge of #59897 - tmandry:variantful-generators, r=eddyb
[rust.git] / src / libstd / sys / redox / ext / net.rs
1 #![stable(feature = "unix_socket_redox", since = "1.29.0")]
2
3 //! Unix-specific networking functionality
4
5 use crate::fmt;
6 use crate::io::{self, Error, ErrorKind, Initializer};
7 use crate::net::Shutdown;
8 use crate::os::unix::io::{RawFd, AsRawFd, FromRawFd, IntoRawFd};
9 use crate::path::Path;
10 use crate::time::Duration;
11 use crate::sys::{cvt, fd::FileDesc, syscall};
12
13 /// An address associated with a Unix socket.
14 ///
15 /// # Examples
16 ///
17 /// ```
18 /// use std::os::unix::net::UnixListener;
19 ///
20 /// let socket = match UnixListener::bind("/tmp/sock") {
21 ///     Ok(sock) => sock,
22 ///     Err(e) => {
23 ///         println!("Couldn't bind: {:?}", e);
24 ///         return
25 ///     }
26 /// };
27 /// let addr = socket.local_addr().expect("Couldn't get local address");
28 /// ```
29 #[derive(Clone)]
30 #[stable(feature = "unix_socket_redox", since = "1.29.0")]
31 pub struct SocketAddr(());
32
33 impl SocketAddr {
34     /// Returns the contents of this address if it is a `pathname` address.
35     ///
36     /// # Examples
37     ///
38     /// With a pathname:
39     ///
40     /// ```no_run
41     /// use std::os::unix::net::UnixListener;
42     /// use std::path::Path;
43     ///
44     /// let socket = UnixListener::bind("/tmp/sock").unwrap();
45     /// let addr = socket.local_addr().expect("Couldn't get local address");
46     /// assert_eq!(addr.as_pathname(), Some(Path::new("/tmp/sock")));
47     /// ```
48     ///
49     /// Without a pathname:
50     ///
51     /// ```
52     /// use std::os::unix::net::UnixDatagram;
53     ///
54     /// let socket = UnixDatagram::unbound().unwrap();
55     /// let addr = socket.local_addr().expect("Couldn't get local address");
56     /// assert_eq!(addr.as_pathname(), None);
57     /// ```
58     #[stable(feature = "unix_socket_redox", since = "1.29.0")]
59     pub fn as_pathname(&self) -> Option<&Path> {
60         None
61     }
62
63     /// Returns `true` if the address is unnamed.
64     ///
65     /// # Examples
66     ///
67     /// A named address:
68     ///
69     /// ```no_run
70     /// use std::os::unix::net::UnixListener;
71     ///
72     /// let socket = UnixListener::bind("/tmp/sock").unwrap();
73     /// let addr = socket.local_addr().expect("Couldn't get local address");
74     /// assert_eq!(addr.is_unnamed(), false);
75     /// ```
76     ///
77     /// An unnamed address:
78     ///
79     /// ```
80     /// use std::os::unix::net::UnixDatagram;
81     ///
82     /// let socket = UnixDatagram::unbound().unwrap();
83     /// let addr = socket.local_addr().expect("Couldn't get local address");
84     /// assert_eq!(addr.is_unnamed(), true);
85     /// ```
86     #[stable(feature = "unix_socket_redox", since = "1.29.0")]
87     pub fn is_unnamed(&self) -> bool {
88         false
89     }
90 }
91 #[stable(feature = "unix_socket_redox", since = "1.29.0")]
92 impl fmt::Debug for SocketAddr {
93     fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
94         write!(fmt, "SocketAddr")
95     }
96 }
97
98 /// A Unix stream socket.
99 ///
100 /// # Examples
101 ///
102 /// ```no_run
103 /// use std::os::unix::net::UnixStream;
104 /// use std::io::prelude::*;
105 ///
106 /// let mut stream = UnixStream::connect("/path/to/my/socket").unwrap();
107 /// stream.write_all(b"hello world").unwrap();
108 /// let mut response = String::new();
109 /// stream.read_to_string(&mut response).unwrap();
110 /// println!("{}", response);
111 /// ```
112 #[stable(feature = "unix_socket_redox", since = "1.29.0")]
113 pub struct UnixStream(FileDesc);
114
115 #[stable(feature = "unix_socket_redox", since = "1.29.0")]
116 impl fmt::Debug for UnixStream {
117     fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
118         let mut builder = fmt.debug_struct("UnixStream");
119         builder.field("fd", &self.0.raw());
120         if let Ok(addr) = self.local_addr() {
121             builder.field("local", &addr);
122         }
123         if let Ok(addr) = self.peer_addr() {
124             builder.field("peer", &addr);
125         }
126         builder.finish()
127     }
128 }
129
130 impl UnixStream {
131     /// Connects to the socket named by `path`.
132     ///
133     /// # Examples
134     ///
135     /// ```no_run
136     /// use std::os::unix::net::UnixStream;
137     ///
138     /// let socket = match UnixStream::connect("/tmp/sock") {
139     ///     Ok(sock) => sock,
140     ///     Err(e) => {
141     ///         println!("Couldn't connect: {:?}", e);
142     ///         return
143     ///     }
144     /// };
145     /// ```
146     #[stable(feature = "unix_socket_redox", since = "1.29.0")]
147     pub fn connect<P: AsRef<Path>>(path: P) -> io::Result<UnixStream> {
148         if let Some(s) = path.as_ref().to_str() {
149             cvt(syscall::open(format!("chan:{}", s), syscall::O_CLOEXEC))
150                 .map(FileDesc::new)
151                 .map(UnixStream)
152         } else {
153             Err(Error::new(
154                 ErrorKind::Other,
155                 "UnixStream::connect: non-utf8 paths not supported on redox"
156             ))
157         }
158     }
159
160     /// Creates an unnamed pair of connected sockets.
161     ///
162     /// Returns two `UnixStream`s which are connected to each other.
163     ///
164     /// # Examples
165     ///
166     /// ```no_run
167     /// use std::os::unix::net::UnixStream;
168     ///
169     /// let (sock1, sock2) = match UnixStream::pair() {
170     ///     Ok((sock1, sock2)) => (sock1, sock2),
171     ///     Err(e) => {
172     ///         println!("Couldn't create a pair of sockets: {:?}", e);
173     ///         return
174     ///     }
175     /// };
176     /// ```
177     #[stable(feature = "unix_socket_redox", since = "1.29.0")]
178     pub fn pair() -> io::Result<(UnixStream, UnixStream)> {
179         let server = cvt(syscall::open("chan:", syscall::O_CREAT | syscall::O_CLOEXEC))
180             .map(FileDesc::new)?;
181         let client = server.duplicate_path(b"connect")?;
182         let stream = server.duplicate_path(b"listen")?;
183         Ok((UnixStream(client), UnixStream(stream)))
184     }
185
186     /// Creates a new independently owned handle to the underlying socket.
187     ///
188     /// The returned `UnixStream` is a reference to the same stream that this
189     /// object references. Both handles will read and write the same stream of
190     /// data, and options set on one stream will be propagated to the other
191     /// stream.
192     ///
193     /// # Examples
194     ///
195     /// ```no_run
196     /// use std::os::unix::net::UnixStream;
197     ///
198     /// let socket = UnixStream::connect("/tmp/sock").unwrap();
199     /// let sock_copy = socket.try_clone().expect("Couldn't clone socket");
200     /// ```
201     #[stable(feature = "unix_socket_redox", since = "1.29.0")]
202     pub fn try_clone(&self) -> io::Result<UnixStream> {
203         self.0.duplicate().map(UnixStream)
204     }
205
206     /// Returns the socket address of the local half of this connection.
207     ///
208     /// # Examples
209     ///
210     /// ```no_run
211     /// use std::os::unix::net::UnixStream;
212     ///
213     /// let socket = UnixStream::connect("/tmp/sock").unwrap();
214     /// let addr = socket.local_addr().expect("Couldn't get local address");
215     /// ```
216     #[stable(feature = "unix_socket_redox", since = "1.29.0")]
217     pub fn local_addr(&self) -> io::Result<SocketAddr> {
218         Err(Error::new(ErrorKind::Other, "UnixStream::local_addr unimplemented on redox"))
219     }
220
221     /// Returns the socket address of the remote half of this connection.
222     ///
223     /// # Examples
224     ///
225     /// ```no_run
226     /// use std::os::unix::net::UnixStream;
227     ///
228     /// let socket = UnixStream::connect("/tmp/sock").unwrap();
229     /// let addr = socket.peer_addr().expect("Couldn't get peer address");
230     /// ```
231     #[stable(feature = "unix_socket_redox", since = "1.29.0")]
232     pub fn peer_addr(&self) -> io::Result<SocketAddr> {
233         Err(Error::new(ErrorKind::Other, "UnixStream::peer_addr unimplemented on redox"))
234     }
235
236     /// Sets the read timeout for the socket.
237     ///
238     /// If the provided value is [`None`], then [`read`] calls will block
239     /// indefinitely. An [`Err`] is returned if the zero [`Duration`] is passed to this
240     /// method.
241     ///
242     /// [`None`]: ../../../../std/option/enum.Option.html#variant.None
243     /// [`Err`]: ../../../../std/result/enum.Result.html#variant.Err
244     /// [`read`]: ../../../../std/io/trait.Read.html#tymethod.read
245     /// [`Duration`]: ../../../../std/time/struct.Duration.html
246     ///
247     /// # Examples
248     ///
249     /// ```no_run
250     /// use std::os::unix::net::UnixStream;
251     /// use std::time::Duration;
252     ///
253     /// let socket = UnixStream::connect("/tmp/sock").unwrap();
254     /// socket.set_read_timeout(Some(Duration::new(1, 0))).expect("Couldn't set read timeout");
255     /// ```
256     ///
257     /// An [`Err`] is returned if the zero [`Duration`] is passed to this
258     /// method:
259     ///
260     /// ```no_run
261     /// use std::io;
262     /// use std::os::unix::net::UnixStream;
263     /// use std::time::Duration;
264     ///
265     /// let socket = UnixStream::connect("/tmp/sock").unwrap();
266     /// let result = socket.set_read_timeout(Some(Duration::new(0, 0)));
267     /// let err = result.unwrap_err();
268     /// assert_eq!(err.kind(), io::ErrorKind::InvalidInput)
269     /// ```
270     #[stable(feature = "unix_socket_redox", since = "1.29.0")]
271     pub fn set_read_timeout(&self, _timeout: Option<Duration>) -> io::Result<()> {
272         Err(Error::new(ErrorKind::Other, "UnixStream::set_read_timeout unimplemented on redox"))
273     }
274
275     /// Sets the write timeout for the socket.
276     ///
277     /// If the provided value is [`None`], then [`write`] calls will block
278     /// indefinitely. An [`Err`] is returned if the zero [`Duration`] is
279     /// passed to this method.
280     ///
281     /// [`None`]: ../../../../std/option/enum.Option.html#variant.None
282     /// [`Err`]: ../../../../std/result/enum.Result.html#variant.Err
283     /// [`write`]: ../../../../std/io/trait.Write.html#tymethod.write
284     /// [`Duration`]: ../../../../std/time/struct.Duration.html
285     ///
286     /// # Examples
287     ///
288     /// ```no_run
289     /// use std::os::unix::net::UnixStream;
290     /// use std::time::Duration;
291     ///
292     /// let socket = UnixStream::connect("/tmp/sock").unwrap();
293     /// socket.set_write_timeout(Some(Duration::new(1, 0))).expect("Couldn't set write timeout");
294     /// ```
295     ///
296     /// An [`Err`] is returned if the zero [`Duration`] is passed to this
297     /// method:
298     ///
299     /// ```no_run
300     /// use std::io;
301     /// use std::net::UdpSocket;
302     /// use std::time::Duration;
303     ///
304     /// let socket = UdpSocket::bind("127.0.0.1:34254").unwrap();
305     /// let result = socket.set_write_timeout(Some(Duration::new(0, 0)));
306     /// let err = result.unwrap_err();
307     /// assert_eq!(err.kind(), io::ErrorKind::InvalidInput)
308     /// ```
309     #[stable(feature = "unix_socket_redox", since = "1.29.0")]
310     pub fn set_write_timeout(&self, _timeout: Option<Duration>) -> io::Result<()> {
311         Err(Error::new(ErrorKind::Other, "UnixStream::set_write_timeout unimplemented on redox"))
312     }
313
314     /// Returns the read timeout of this socket.
315     ///
316     /// # Examples
317     ///
318     /// ```no_run
319     /// use std::os::unix::net::UnixStream;
320     /// use std::time::Duration;
321     ///
322     /// let socket = UnixStream::connect("/tmp/sock").unwrap();
323     /// socket.set_read_timeout(Some(Duration::new(1, 0))).expect("Couldn't set read timeout");
324     /// assert_eq!(socket.read_timeout().unwrap(), Some(Duration::new(1, 0)));
325     /// ```
326     #[stable(feature = "unix_socket_redox", since = "1.29.0")]
327     pub fn read_timeout(&self) -> io::Result<Option<Duration>> {
328         Err(Error::new(ErrorKind::Other, "UnixStream::read_timeout unimplemented on redox"))
329     }
330
331     /// Returns the write timeout of this socket.
332     ///
333     /// # Examples
334     ///
335     /// ```no_run
336     /// use std::os::unix::net::UnixStream;
337     /// use std::time::Duration;
338     ///
339     /// let socket = UnixStream::connect("/tmp/sock").unwrap();
340     /// socket.set_write_timeout(Some(Duration::new(1, 0))).expect("Couldn't set write timeout");
341     /// assert_eq!(socket.write_timeout().unwrap(), Some(Duration::new(1, 0)));
342     /// ```
343     #[stable(feature = "unix_socket_redox", since = "1.29.0")]
344     pub fn write_timeout(&self) -> io::Result<Option<Duration>> {
345         Err(Error::new(ErrorKind::Other, "UnixStream::write_timeout unimplemented on redox"))
346     }
347
348     /// Moves the socket into or out of nonblocking mode.
349     ///
350     /// # Examples
351     ///
352     /// ```no_run
353     /// use std::os::unix::net::UnixStream;
354     ///
355     /// let socket = UnixStream::connect("/tmp/sock").unwrap();
356     /// socket.set_nonblocking(true).expect("Couldn't set nonblocking");
357     /// ```
358     #[stable(feature = "unix_socket_redox", since = "1.29.0")]
359     pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
360         self.0.set_nonblocking(nonblocking)
361     }
362
363     /// Returns the value of the `SO_ERROR` option.
364     ///
365     /// # Examples
366     ///
367     /// ```no_run
368     /// use std::os::unix::net::UnixStream;
369     ///
370     /// let socket = UnixStream::connect("/tmp/sock").unwrap();
371     /// if let Ok(Some(err)) = socket.take_error() {
372     ///     println!("Got error: {:?}", err);
373     /// }
374     /// ```
375     ///
376     /// # Platform specific
377     /// On Redox this always returns `None`.
378     #[stable(feature = "unix_socket_redox", since = "1.29.0")]
379     pub fn take_error(&self) -> io::Result<Option<io::Error>> {
380         Ok(None)
381     }
382
383     /// Shuts down the read, write, or both halves of this connection.
384     ///
385     /// This function will cause all pending and future I/O calls on the
386     /// specified portions to immediately return with an appropriate value
387     /// (see the documentation of [`Shutdown`]).
388     ///
389     /// [`Shutdown`]: ../../../../std/net/enum.Shutdown.html
390     ///
391     /// # Examples
392     ///
393     /// ```no_run
394     /// use std::os::unix::net::UnixStream;
395     /// use std::net::Shutdown;
396     ///
397     /// let socket = UnixStream::connect("/tmp/sock").unwrap();
398     /// socket.shutdown(Shutdown::Both).expect("shutdown function failed");
399     /// ```
400     #[stable(feature = "unix_socket_redox", since = "1.29.0")]
401     pub fn shutdown(&self, _how: Shutdown) -> io::Result<()> {
402         Err(Error::new(ErrorKind::Other, "UnixStream::shutdown unimplemented on redox"))
403     }
404 }
405
406 #[stable(feature = "unix_socket_redox", since = "1.29.0")]
407 impl io::Read for UnixStream {
408     fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
409         io::Read::read(&mut &*self, buf)
410     }
411
412     #[inline]
413     unsafe fn initializer(&self) -> Initializer {
414         Initializer::nop()
415     }
416 }
417
418 #[stable(feature = "unix_socket_redox", since = "1.29.0")]
419 impl<'a> io::Read for &'a UnixStream {
420     fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
421         self.0.read(buf)
422     }
423
424     #[inline]
425     unsafe fn initializer(&self) -> Initializer {
426         Initializer::nop()
427     }
428 }
429
430 #[stable(feature = "unix_socket_redox", since = "1.29.0")]
431 impl io::Write for UnixStream {
432     fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
433         io::Write::write(&mut &*self, buf)
434     }
435
436     fn flush(&mut self) -> io::Result<()> {
437         io::Write::flush(&mut &*self)
438     }
439 }
440
441 #[stable(feature = "unix_socket_redox", since = "1.29.0")]
442 impl<'a> io::Write for &'a UnixStream {
443     fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
444         self.0.write(buf)
445     }
446
447     fn flush(&mut self) -> io::Result<()> {
448         Ok(())
449     }
450 }
451
452 #[stable(feature = "unix_socket_redox", since = "1.29.0")]
453 impl AsRawFd for UnixStream {
454     fn as_raw_fd(&self) -> RawFd {
455         self.0.raw()
456     }
457 }
458
459 #[stable(feature = "unix_socket_redox", since = "1.29.0")]
460 impl FromRawFd for UnixStream {
461     unsafe fn from_raw_fd(fd: RawFd) -> UnixStream {
462         UnixStream(FileDesc::new(fd))
463     }
464 }
465
466 #[stable(feature = "unix_socket_redox", since = "1.29.0")]
467 impl IntoRawFd for UnixStream {
468     fn into_raw_fd(self) -> RawFd {
469         self.0.into_raw()
470     }
471 }
472
473 /// A structure representing a Unix domain socket server.
474 ///
475 /// # Examples
476 ///
477 /// ```no_run
478 /// use std::thread;
479 /// use std::os::unix::net::{UnixStream, UnixListener};
480 ///
481 /// fn handle_client(stream: UnixStream) {
482 ///     // ...
483 /// }
484 ///
485 /// let listener = UnixListener::bind("/path/to/the/socket").unwrap();
486 ///
487 /// // accept connections and process them, spawning a new thread for each one
488 /// for stream in listener.incoming() {
489 ///     match stream {
490 ///         Ok(stream) => {
491 ///             /* connection succeeded */
492 ///             thread::spawn(|| handle_client(stream));
493 ///         }
494 ///         Err(err) => {
495 ///             /* connection failed */
496 ///             break;
497 ///         }
498 ///     }
499 /// }
500 /// ```
501 #[stable(feature = "unix_socket_redox", since = "1.29.0")]
502 pub struct UnixListener(FileDesc);
503
504 #[stable(feature = "unix_socket_redox", since = "1.29.0")]
505 impl fmt::Debug for UnixListener {
506     fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
507         let mut builder = fmt.debug_struct("UnixListener");
508         builder.field("fd", &self.0.raw());
509         if let Ok(addr) = self.local_addr() {
510             builder.field("local", &addr);
511         }
512         builder.finish()
513     }
514 }
515
516 impl UnixListener {
517     /// Creates a new `UnixListener` bound to the specified socket.
518     ///
519     /// # Examples
520     ///
521     /// ```no_run
522     /// use std::os::unix::net::UnixListener;
523     ///
524     /// let listener = match UnixListener::bind("/path/to/the/socket") {
525     ///     Ok(sock) => sock,
526     ///     Err(e) => {
527     ///         println!("Couldn't connect: {:?}", e);
528     ///         return
529     ///     }
530     /// };
531     /// ```
532     #[stable(feature = "unix_socket_redox", since = "1.29.0")]
533     pub fn bind<P: AsRef<Path>>(path: P) -> io::Result<UnixListener> {
534         if let Some(s) = path.as_ref().to_str() {
535             cvt(syscall::open(format!("chan:{}", s), syscall::O_CREAT | syscall::O_CLOEXEC))
536                 .map(FileDesc::new)
537                 .map(UnixListener)
538         } else {
539             Err(Error::new(
540                 ErrorKind::Other,
541                 "UnixListener::bind: non-utf8 paths not supported on redox"
542             ))
543         }
544     }
545
546     /// Accepts a new incoming connection to this listener.
547     ///
548     /// This function will block the calling thread until a new Unix connection
549     /// is established. When established, the corresponding [`UnixStream`] and
550     /// the remote peer's address will be returned.
551     ///
552     /// [`UnixStream`]: ../../../../std/os/unix/net/struct.UnixStream.html
553     ///
554     /// # Examples
555     ///
556     /// ```no_run
557     /// use std::os::unix::net::UnixListener;
558     ///
559     /// let listener = UnixListener::bind("/path/to/the/socket").unwrap();
560     ///
561     /// match listener.accept() {
562     ///     Ok((socket, addr)) => println!("Got a client: {:?}", addr),
563     ///     Err(e) => println!("accept function failed: {:?}", e),
564     /// }
565     /// ```
566     #[stable(feature = "unix_socket_redox", since = "1.29.0")]
567     pub fn accept(&self) -> io::Result<(UnixStream, SocketAddr)> {
568         self.0.duplicate_path(b"listen").map(|fd| (UnixStream(fd), SocketAddr(())))
569     }
570
571     /// Creates a new independently owned handle to the underlying socket.
572     ///
573     /// The returned `UnixListener` is a reference to the same socket that this
574     /// object references. Both handles can be used to accept incoming
575     /// connections and options set on one listener will affect the other.
576     ///
577     /// # Examples
578     ///
579     /// ```no_run
580     /// use std::os::unix::net::UnixListener;
581     ///
582     /// let listener = UnixListener::bind("/path/to/the/socket").unwrap();
583     ///
584     /// let listener_copy = listener.try_clone().expect("try_clone failed");
585     /// ```
586     #[stable(feature = "unix_socket_redox", since = "1.29.0")]
587     pub fn try_clone(&self) -> io::Result<UnixListener> {
588         self.0.duplicate().map(UnixListener)
589     }
590
591     /// Returns the local socket address of this listener.
592     ///
593     /// # Examples
594     ///
595     /// ```no_run
596     /// use std::os::unix::net::UnixListener;
597     ///
598     /// let listener = UnixListener::bind("/path/to/the/socket").unwrap();
599     ///
600     /// let addr = listener.local_addr().expect("Couldn't get local address");
601     /// ```
602     #[stable(feature = "unix_socket_redox", since = "1.29.0")]
603     pub fn local_addr(&self) -> io::Result<SocketAddr> {
604         Err(Error::new(ErrorKind::Other, "UnixListener::local_addr unimplemented on redox"))
605     }
606
607     /// Moves the socket into or out of nonblocking mode.
608     ///
609     /// # Examples
610     ///
611     /// ```no_run
612     /// use std::os::unix::net::UnixListener;
613     ///
614     /// let listener = UnixListener::bind("/path/to/the/socket").unwrap();
615     ///
616     /// listener.set_nonblocking(true).expect("Couldn't set non blocking");
617     /// ```
618     #[stable(feature = "unix_socket_redox", since = "1.29.0")]
619     pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
620         self.0.set_nonblocking(nonblocking)
621     }
622
623     /// Returns the value of the `SO_ERROR` option.
624     ///
625     /// # Examples
626     ///
627     /// ```no_run
628     /// use std::os::unix::net::UnixListener;
629     ///
630     /// let listener = UnixListener::bind("/tmp/sock").unwrap();
631     ///
632     /// if let Ok(Some(err)) = listener.take_error() {
633     ///     println!("Got error: {:?}", err);
634     /// }
635     /// ```
636     ///
637     /// # Platform specific
638     /// On Redox this always returns `None`.
639     #[stable(feature = "unix_socket_redox", since = "1.29.0")]
640     pub fn take_error(&self) -> io::Result<Option<io::Error>> {
641         Ok(None)
642     }
643
644     /// Returns an iterator over incoming connections.
645     ///
646     /// The iterator will never return [`None`] and will also not yield the
647     /// peer's [`SocketAddr`] structure.
648     ///
649     /// [`None`]: ../../../../std/option/enum.Option.html#variant.None
650     /// [`SocketAddr`]: struct.SocketAddr.html
651     ///
652     /// # Examples
653     ///
654     /// ```no_run
655     /// use std::thread;
656     /// use std::os::unix::net::{UnixStream, UnixListener};
657     ///
658     /// fn handle_client(stream: UnixStream) {
659     ///     // ...
660     /// }
661     ///
662     /// let listener = UnixListener::bind("/path/to/the/socket").unwrap();
663     ///
664     /// for stream in listener.incoming() {
665     ///     match stream {
666     ///         Ok(stream) => {
667     ///             thread::spawn(|| handle_client(stream));
668     ///         }
669     ///         Err(err) => {
670     ///             break;
671     ///         }
672     ///     }
673     /// }
674     /// ```
675     #[stable(feature = "unix_socket_redox", since = "1.29.0")]
676     pub fn incoming<'a>(&'a self) -> Incoming<'a> {
677         Incoming { listener: self }
678     }
679 }
680
681 #[stable(feature = "unix_socket_redox", since = "1.29.0")]
682 impl AsRawFd for UnixListener {
683     fn as_raw_fd(&self) -> RawFd {
684         self.0.raw()
685     }
686 }
687
688 #[stable(feature = "unix_socket_redox", since = "1.29.0")]
689 impl FromRawFd for UnixListener {
690     unsafe fn from_raw_fd(fd: RawFd) -> UnixListener {
691         UnixListener(FileDesc::new(fd))
692     }
693 }
694
695 #[stable(feature = "unix_socket_redox", since = "1.29.0")]
696 impl IntoRawFd for UnixListener {
697     fn into_raw_fd(self) -> RawFd {
698         self.0.into_raw()
699     }
700 }
701
702 #[stable(feature = "unix_socket_redox", since = "1.29.0")]
703 impl<'a> IntoIterator for &'a UnixListener {
704     type Item = io::Result<UnixStream>;
705     type IntoIter = Incoming<'a>;
706
707     fn into_iter(self) -> Incoming<'a> {
708         self.incoming()
709     }
710 }
711
712 /// An iterator over incoming connections to a [`UnixListener`].
713 ///
714 /// It will never return [`None`].
715 ///
716 /// [`None`]: ../../../../std/option/enum.Option.html#variant.None
717 /// [`UnixListener`]: struct.UnixListener.html
718 ///
719 /// # Examples
720 ///
721 /// ```no_run
722 /// use std::thread;
723 /// use std::os::unix::net::{UnixStream, UnixListener};
724 ///
725 /// fn handle_client(stream: UnixStream) {
726 ///     // ...
727 /// }
728 ///
729 /// let listener = UnixListener::bind("/path/to/the/socket").unwrap();
730 ///
731 /// for stream in listener.incoming() {
732 ///     match stream {
733 ///         Ok(stream) => {
734 ///             thread::spawn(|| handle_client(stream));
735 ///         }
736 ///         Err(err) => {
737 ///             break;
738 ///         }
739 ///     }
740 /// }
741 /// ```
742 #[derive(Debug)]
743 #[stable(feature = "unix_socket_redox", since = "1.29.0")]
744 pub struct Incoming<'a> {
745     listener: &'a UnixListener,
746 }
747
748 #[stable(feature = "unix_socket_redox", since = "1.29.0")]
749 impl<'a> Iterator for Incoming<'a> {
750     type Item = io::Result<UnixStream>;
751
752     fn next(&mut self) -> Option<io::Result<UnixStream>> {
753         Some(self.listener.accept().map(|s| s.0))
754     }
755
756     fn size_hint(&self) -> (usize, Option<usize>) {
757         (usize::max_value(), None)
758     }
759 }