@@ -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,14 @@ impl fmt::Debug for UnixListener {
5354}
5455
5556impl UnixListener {
57+ /// Default backlog for `bind` and `bind_addr`.
58+ const DEFAULT_BACKLOG : usize = 128 ;
59+
5660 /// Creates a new `UnixListener` bound to the specified socket.
5761 ///
62+ /// The listener will have a backlog of 128. See the documentation for
63+ /// [`UnixListener::bind_with_backlog`] for further information.
64+ ///
5865 /// # Examples
5966 ///
6067 /// ```no_run
@@ -70,19 +77,61 @@ impl UnixListener {
7077 /// ```
7178 #[ stable( feature = "unix_socket" , since = "1.10.0" ) ]
7279 pub fn bind < P : AsRef < Path > > ( path : P ) -> io:: Result < UnixListener > {
80+ UnixListener :: bind_with_backlog ( path, UnixListener :: DEFAULT_BACKLOG )
81+ }
82+
83+ /// Creates a new `UnixListener` bound to the specified socket.
84+ ///
85+ /// The given backlog specifies the maximum number of outstanding
86+ /// connections that will be buffered in the OS waiting to be accepted
87+ /// by [`UnixListener::accept`]. The backlog argument overrides the
88+ /// default backlog of 128; that default is reasonable for most use
89+ /// cases.
90+ ///
91+ /// This function is otherwise [`UnixListener::bind`]: see that
92+ /// documentation for full details of operation.
93+ ///
94+ /// # Examples
95+ ///
96+ /// ```no_run
97+ /// #![feature(bind_with_backlog)]
98+ /// use std::os::unix::net::UnixListener;
99+ ///
100+ /// let listener = match UnixListener::bind_with_backlog("/path/to/the/socket", 1000) {
101+ /// Ok(sock) => sock,
102+ /// Err(e) => {
103+ /// println!("Couldn't connect: {:?}", e);
104+ /// return
105+ /// }
106+ /// };
107+ /// ```
108+ ///
109+ /// # Errors
110+ ///
111+ /// The specified backlog may be larger than supported by the underlying
112+ /// system. In this case an [`io::Error`] with
113+ /// [`io::ErrorKind::InvalidData`] will be returned.
114+ #[ unstable( feature = "bind_with_backlog" , issue = "94406" ) ]
115+ pub fn bind_with_backlog < P : AsRef < Path > > ( path : P , backlog : usize ) -> io:: Result < UnixListener > {
73116 unsafe {
117+ let backlog = backlog
118+ . try_into ( )
119+ . map_err ( |e| crate :: io:: Error :: new ( crate :: io:: ErrorKind :: InvalidData , e) ) ?;
74120 let inner = Socket :: new_raw ( libc:: AF_UNIX , libc:: SOCK_STREAM ) ?;
75121 let ( addr, len) = sockaddr_un ( path. as_ref ( ) ) ?;
76122
77123 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 ) ) ?;
124+ cvt ( libc:: listen ( inner. as_inner ( ) . as_raw_fd ( ) , backlog ) ) ?;
79125
80126 Ok ( UnixListener ( inner) )
81127 }
82128 }
83129
84130 /// Creates a new `UnixListener` bound to the specified [`socket address`].
85131 ///
132+ /// The listener will have a backlog of 128. See the documentation for
133+ /// [`UnixListener::bind_addr_with_backlog`] for further information.
134+ ///
86135 /// [`socket address`]: crate::os::unix::net::SocketAddr
87136 ///
88137 /// # Examples
@@ -107,14 +156,59 @@ 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
166+ /// by [`UnixListener::accept`]. The backlog argument overrides the
167+ /// default of 128; that default is reasonable for most use cases.
168+ ///
169+ /// This function is otherwise [`UnixListener::bind_addr`]: see that
170+ /// documentation for full details of operation.
171+ ///
172+ /// [`socket address`]: crate::os::unix::net::SocketAddr
173+ ///
174+ /// # Examples
175+ ///
176+ /// ```no_run
177+ /// #![feature(unix_socket_abstract)]
178+ /// #![feature(bind_with_backlog)]
179+ /// use std::os::unix::net::{UnixListener};
180+ ///
181+ /// fn main() -> std::io::Result<()> {
182+ /// let listener1 = UnixListener::bind("path/to/socket")?;
183+ /// let addr = listener1.local_addr()?;
184+ ///
185+ /// let listener2 = match UnixListener::bind_addr_with_backlog(&addr, 1000) {
186+ /// Ok(sock) => sock,
187+ /// Err(err) => {
188+ /// println!("Couldn't bind: {:?}", err);
189+ /// return Err(err);
190+ /// }
191+ /// };
192+ /// Ok(())
193+ /// }
194+ /// ```
195+ //#[unstable(feature = "unix_socket_abstract", issue = "85410")]
196+ #[ unstable( feature = "bind_with_backlog" , issue = "94406" ) ]
197+ pub fn bind_addr_with_backlog (
198+ socket_addr : & SocketAddr ,
199+ backlog : usize ,
200+ ) -> io:: Result < UnixListener > {
110201 unsafe {
202+ let backlog = backlog
203+ . try_into ( )
204+ . map_err ( |e| crate :: io:: Error :: new ( crate :: io:: ErrorKind :: InvalidData , e) ) ?;
111205 let inner = Socket :: new_raw ( libc:: AF_UNIX , libc:: SOCK_STREAM ) ?;
112206 cvt ( libc:: bind (
113207 inner. as_raw_fd ( ) ,
114208 & socket_addr. addr as * const _ as * const _ ,
115209 socket_addr. len as _ ,
116210 ) ) ?;
117- cvt ( libc:: listen ( inner. as_raw_fd ( ) , 128 ) ) ?;
211+ cvt ( libc:: listen ( inner. as_raw_fd ( ) , backlog ) ) ?;
118212 Ok ( UnixListener ( inner) )
119213 }
120214 }
0 commit comments