@@ -5,6 +5,7 @@ use crate::sys::cvt;
5
5
use crate :: sys:: net:: Socket ;
6
6
use crate :: sys_common:: { AsInner , FromInner , IntoInner } ;
7
7
use crate :: { fmt, io, mem} ;
8
+ use core:: convert:: TryInto ;
8
9
9
10
/// A structure representing a Unix domain socket server.
10
11
///
@@ -53,8 +54,18 @@ impl fmt::Debug for UnixListener {
53
54
}
54
55
55
56
impl 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
+
56
63
/// Creates a new `UnixListener` bound to the specified socket.
57
64
///
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
+ ///
58
69
/// # Examples
59
70
///
60
71
/// ```no_run
@@ -70,12 +81,50 @@ impl UnixListener {
70
81
/// ```
71
82
#[ stable( feature = "unix_socket" , since = "1.10.0" ) ]
72
83
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 > {
73
119
unsafe {
120
+ let backlog = backlog
121
+ . try_into ( )
122
+ . map_err ( |e| crate :: io:: Error :: new ( crate :: io:: ErrorKind :: InvalidData , e) ) ?;
74
123
let inner = Socket :: new_raw ( libc:: AF_UNIX , libc:: SOCK_STREAM ) ?;
75
124
let ( addr, len) = sockaddr_un ( path. as_ref ( ) ) ?;
76
125
77
126
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 ) ) ?;
79
128
80
129
Ok ( UnixListener ( inner) )
81
130
}
@@ -107,14 +156,60 @@ impl UnixListener {
107
156
/// ```
108
157
#[ unstable( feature = "unix_socket_abstract" , issue = "85410" ) ]
109
158
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 > {
110
202
unsafe {
203
+ let backlog = backlog
204
+ . try_into ( )
205
+ . map_err ( |e| crate :: io:: Error :: new ( crate :: io:: ErrorKind :: InvalidData , e) ) ?;
111
206
let inner = Socket :: new_raw ( libc:: AF_UNIX , libc:: SOCK_STREAM ) ?;
112
207
cvt ( libc:: bind (
113
208
inner. as_raw_fd ( ) ,
114
209
& socket_addr. addr as * const _ as * const _ ,
115
210
socket_addr. len as _ ,
116
211
) ) ?;
117
- cvt ( libc:: listen ( inner. as_raw_fd ( ) , 128 ) ) ?;
212
+ cvt ( libc:: listen ( inner. as_raw_fd ( ) , backlog ) ) ?;
118
213
Ok ( UnixListener ( inner) )
119
214
}
120
215
}
0 commit comments