@@ -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,14 @@ impl fmt::Debug for UnixListener {
53
54
}
54
55
55
56
impl UnixListener {
57
+ /// Default backlog for `bind` and `bind_addr`.
58
+ const DEFAULT_BACKLOG : usize = 128 ;
59
+
56
60
/// Creates a new `UnixListener` bound to the specified socket.
57
61
///
62
+ /// The listener will have a backlog of 128. See the documentation for
63
+ /// [`UnixListener::bind_with_backlog`] for further information.
64
+ ///
58
65
/// # Examples
59
66
///
60
67
/// ```no_run
@@ -70,19 +77,61 @@ impl UnixListener {
70
77
/// ```
71
78
#[ stable( feature = "unix_socket" , since = "1.10.0" ) ]
72
79
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 > {
73
116
unsafe {
117
+ let backlog = backlog
118
+ . try_into ( )
119
+ . map_err ( |e| crate :: io:: Error :: new ( crate :: io:: ErrorKind :: InvalidData , e) ) ?;
74
120
let inner = Socket :: new_raw ( libc:: AF_UNIX , libc:: SOCK_STREAM ) ?;
75
121
let ( addr, len) = sockaddr_un ( path. as_ref ( ) ) ?;
76
122
77
123
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 ) ) ?;
79
125
80
126
Ok ( UnixListener ( inner) )
81
127
}
82
128
}
83
129
84
130
/// Creates a new `UnixListener` bound to the specified [`socket address`].
85
131
///
132
+ /// The listener will have a backlog of 128. See the documentation for
133
+ /// [`UnixListener::bind_addr_with_backlog`] for further information.
134
+ ///
86
135
/// [`socket address`]: crate::os::unix::net::SocketAddr
87
136
///
88
137
/// # Examples
@@ -107,14 +156,59 @@ 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
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 > {
110
201
unsafe {
202
+ let backlog = backlog
203
+ . try_into ( )
204
+ . map_err ( |e| crate :: io:: Error :: new ( crate :: io:: ErrorKind :: InvalidData , e) ) ?;
111
205
let inner = Socket :: new_raw ( libc:: AF_UNIX , libc:: SOCK_STREAM ) ?;
112
206
cvt ( libc:: bind (
113
207
inner. as_raw_fd ( ) ,
114
208
& socket_addr. addr as * const _ as * const _ ,
115
209
socket_addr. len as _ ,
116
210
) ) ?;
117
- cvt ( libc:: listen ( inner. as_raw_fd ( ) , 128 ) ) ?;
211
+ cvt ( libc:: listen ( inner. as_raw_fd ( ) , backlog ) ) ?;
118
212
Ok ( UnixListener ( inner) )
119
213
}
120
214
}
0 commit comments