@@ -5,6 +5,7 @@ use crate::sys::cvt;
55use crate :: sys:: net:: Socket ;
66use crate :: sys_common:: { AsInner , FromInner , IntoInner } ;
77use crate :: { fmt, io, mem} ;
8+ use core:: convert:: TryInto ;
89
910/// A structure representing a Unix domain socket server.
1011///
@@ -53,8 +54,18 @@ impl fmt::Debug for UnixListener {
5354}
5455
5556impl UnixListener {
57+ /// Default "backlog" for [`UnixListener::bind`] and
58+ /// [`UnixListener::bind_addr`]. See [`UnixListener::bind_with_backlog`]
59+ /// for an explanation of backlog values.
60+ #[ unstable( feature = "bind_with_backlog" , issue = "none" ) ]
61+ pub const DEFAULT_BACKLOG : usize = 128 ;
62+
5663 /// Creates a new `UnixListener` bound to the specified socket.
5764 ///
65+ /// The listener will have a backlog given by
66+ /// [`UnixListener::DEFAULT_BACKLOG`]. See the documentation for
67+ /// [`UnixListener::bind_with_backlog`] for further information.
68+ ///
5869 /// # Examples
5970 ///
6071 /// ```no_run
@@ -70,12 +81,50 @@ impl UnixListener {
7081 /// ```
7182 #[ stable( feature = "unix_socket" , since = "1.10.0" ) ]
7283 pub fn bind < P : AsRef < Path > > ( path : P ) -> io:: Result < UnixListener > {
84+ UnixListener :: bind_with_backlog ( path, UnixListener :: DEFAULT_BACKLOG )
85+ }
86+
87+ /// Creates a new `UnixListener` bound to the specified socket.
88+ ///
89+ /// The given backlog specifies the maximum number of outstanding
90+ /// connections that will be buffered in the OS waiting to be accepted by
91+ /// [`UnixListener::accept`]. The backlog argument overrides the default
92+ /// specified by [`UnixListener::DEFAULT_BACKLOG`]; that default is
93+ /// reasonable for most use cases.
94+ ///
95+ /// This function is otherwise [`UnixListener::bind`]: see that
96+ /// documentation for full details of operation.
97+ ///
98+ /// # Examples
99+ ///
100+ /// ```no_run
101+ /// use std::os::unix::net::UnixListener;
102+ ///
103+ /// let listener = match UnixListener::bind_with_backlog("/path/to/the/socket", 1000) {
104+ /// Ok(sock) => sock,
105+ /// Err(e) => {
106+ /// println!("Couldn't connect: {:?}", e);
107+ /// return
108+ /// }
109+ /// };
110+ /// ```
111+ ///
112+ /// # Errors
113+ ///
114+ /// The specified backlog may be larger than supported by the underlying
115+ /// system. In this case an [`io::Error`] with
116+ /// [`io::ErrorKind::InvalidData`] will be returned.
117+ #[ unstable( feature = "bind_with_backlog" , issue = "none" ) ]
118+ pub fn bind_with_backlog < P : AsRef < Path > > ( path : P , backlog : usize ) -> io:: Result < UnixListener > {
73119 unsafe {
120+ let backlog = backlog
121+ . try_into ( )
122+ . map_err ( |e| crate :: io:: Error :: new ( crate :: io:: ErrorKind :: InvalidData , e) ) ?;
74123 let inner = Socket :: new_raw ( libc:: AF_UNIX , libc:: SOCK_STREAM ) ?;
75124 let ( addr, len) = sockaddr_un ( path. as_ref ( ) ) ?;
76125
77126 cvt ( libc:: bind ( inner. as_inner ( ) . as_raw_fd ( ) , & addr as * const _ as * const _ , len as _ ) ) ?;
78- cvt ( libc:: listen ( inner. as_inner ( ) . as_raw_fd ( ) , 128 ) ) ?;
127+ cvt ( libc:: listen ( inner. as_inner ( ) . as_raw_fd ( ) , backlog ) ) ?;
79128
80129 Ok ( UnixListener ( inner) )
81130 }
@@ -107,14 +156,60 @@ impl UnixListener {
107156 /// ```
108157 #[ unstable( feature = "unix_socket_abstract" , issue = "85410" ) ]
109158 pub fn bind_addr ( socket_addr : & SocketAddr ) -> io:: Result < UnixListener > {
159+ UnixListener :: bind_addr_with_backlog ( socket_addr, UnixListener :: DEFAULT_BACKLOG )
160+ }
161+
162+ /// Creates a new `UnixListener` bound to the specified [`socket address`].
163+ ///
164+ /// The given backlog specifies the maximum number of outstanding
165+ /// connections that will be buffered in the OS waiting to be accepted by
166+ /// [`UnixListener::accept`]. The backlog argument overrides the default
167+ /// specified by [`UnixListener::DEFAULT_BACKLOG`]; that default is
168+ /// reasonable for most use cases.
169+ ///
170+ /// This function is otherwise [`UnixListener::bind_addr`]: see that
171+ /// documentation for full details of operation.
172+ ///
173+ /// [`socket address`]: crate::os::unix::net::SocketAddr
174+ ///
175+ /// # Examples
176+ ///
177+ /// ```no_run
178+ /// #![feature(unix_socket_abstract)]
179+ /// #![feature(bind_with_backlog)]
180+ /// use std::os::unix::net::{UnixListener};
181+ ///
182+ /// fn main() -> std::io::Result<()> {
183+ /// let listener1 = UnixListener::bind("path/to/socket")?;
184+ /// let addr = listener1.local_addr()?;
185+ ///
186+ /// let listener2 = match UnixListener::bind_addr_with_backlog(&addr, 1000) {
187+ /// Ok(sock) => sock,
188+ /// Err(err) => {
189+ /// println!("Couldn't bind: {:?}", err);
190+ /// return Err(err);
191+ /// }
192+ /// };
193+ /// Ok(())
194+ /// }
195+ /// ```
196+ //#[unstable(feature = "unix_socket_abstract", issue = "85410")]
197+ #[ unstable( feature = "bind_with_backlog" , issue = "none" ) ]
198+ pub fn bind_addr_with_backlog (
199+ socket_addr : & SocketAddr ,
200+ backlog : usize ,
201+ ) -> io:: Result < UnixListener > {
110202 unsafe {
203+ let backlog = backlog
204+ . try_into ( )
205+ . map_err ( |e| crate :: io:: Error :: new ( crate :: io:: ErrorKind :: InvalidData , e) ) ?;
111206 let inner = Socket :: new_raw ( libc:: AF_UNIX , libc:: SOCK_STREAM ) ?;
112207 cvt ( libc:: bind (
113208 inner. as_raw_fd ( ) ,
114209 & socket_addr. addr as * const _ as * const _ ,
115210 socket_addr. len as _ ,
116211 ) ) ?;
117- cvt ( libc:: listen ( inner. as_raw_fd ( ) , 128 ) ) ?;
212+ cvt ( libc:: listen ( inner. as_raw_fd ( ) , backlog ) ) ?;
118213 Ok ( UnixListener ( inner) )
119214 }
120215 }
0 commit comments