diff --git a/changelog/2573.added.md b/changelog/2573.added.md new file mode 100644 index 0000000000..1b312aa861 --- /dev/null +++ b/changelog/2573.added.md @@ -0,0 +1 @@ +Added `sockopt::EsclBind` for solarish targets diff --git a/src/sys/socket/sockopt.rs b/src/sys/socket/sockopt.rs index cfa407de00..1b61e976f0 100644 --- a/src/sys/socket/sockopt.rs +++ b/src/sys/socket/sockopt.rs @@ -1257,6 +1257,18 @@ sockopt_impl!( GetCString<[u8; libc::IFNAMSIZ]> ); +#[cfg(solarish)] +sockopt_impl!( + /// Enable/disable exclusive binding. + /// Prevent multiple sockets to bind to the same + /// address:port, neutralizing `SO_REUSEADDR` effect. + ExclBind, + Both, + libc::SOL_SOCKET, + libc::SO_EXCLBIND, + bool +); + #[allow(missing_docs)] // Not documented by Linux! #[cfg(linux_android)] diff --git a/test/sys/test_sockopt.rs b/test/sys/test_sockopt.rs index 83f796e44c..42697ffa24 100644 --- a/test/sys/test_sockopt.rs +++ b/test/sys/test_sockopt.rs @@ -1133,3 +1133,38 @@ mod sockopt_impl { assert_eq!(get_linger.l_linger, set_linger.l_linger); } } + +#[cfg(solarish)] +#[test] +fn test_exclbind() { + use nix::errno::Errno; + use nix::sys::socket::{ + bind, socket, AddressFamily, SockFlag, SockType, SockaddrIn, + }; + use std::net::SocketAddrV4; + use std::str::FromStr; + let fd1 = socket( + AddressFamily::Inet, + SockType::Stream, + SockFlag::empty(), + None, + ) + .unwrap(); + let addr = SocketAddrV4::from_str("127.0.0.1:8081").unwrap(); + let excl = true; + + setsockopt(&fd1, sockopt::ExclBind, &excl).unwrap(); + bind(fd1.as_raw_fd(), &SockaddrIn::from(addr)).unwrap(); + assert_eq!(getsockopt(&fd1, sockopt::ExclBind), Ok(true)); + let fd2 = socket( + AddressFamily::Inet, + SockType::Stream, + SockFlag::empty(), + None, + ) + .unwrap(); + assert_eq!( + bind(fd2.as_raw_fd(), &SockaddrIn::from(addr)), + Err(Errno::EADDRINUSE) + ); +}