Skip to content

Commit 6f03b95

Browse files
committed
added UnixListener::bind_with_backlog and UnixListener::bind_addr_with_backlog
Also added UnixListener::DEFAULT_BACKLOG
1 parent 530e2dd commit 6f03b95

File tree

1 file changed

+97
-2
lines changed

1 file changed

+97
-2
lines changed

library/std/src/os/unix/net/listener.rs

Lines changed: 97 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use crate::sys::cvt;
55
use crate::sys::net::Socket;
66
use crate::sys_common::{AsInner, FromInner, IntoInner};
77
use 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

5556
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+
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

Comments
 (0)