@@ -2009,12 +2009,130 @@ pub fn socketpair<T: Into<Option<SockProtocol>>>(
2009
2009
unsafe { Ok ( ( OwnedFd :: from_raw_fd ( fds[ 0 ] ) , OwnedFd :: from_raw_fd ( fds[ 1 ] ) ) ) }
2010
2010
}
2011
2011
2012
+ #[ derive( Debug , Clone , Copy , PartialEq , Eq ) ]
2013
+ pub struct Backlog ( i32 ) ;
2014
+
2015
+ impl Backlog {
2016
+ /// Sets the listen queue size to system `SOMAXCONN` value
2017
+ pub const MAXCONN : Self = Self ( libc:: SOMAXCONN ) ;
2018
+ /// Sets the listen queue size to -1 for system supporting it
2019
+ #[ cfg( any( target_os = "linux" , target_os = "freebsd" ) ) ]
2020
+ pub const MAXALLOWABLE : Self = Self ( -1 ) ;
2021
+ }
2022
+
2023
+ #[ derive( Debug , Clone , Copy , PartialEq , Eq ) ]
2024
+ pub enum BacklogTryFromError {
2025
+ TooNegative ,
2026
+ TooPositive ,
2027
+ }
2028
+
2029
+ impl std:: fmt:: Display for BacklogTryFromError {
2030
+ fn fmt ( & self , f : & mut std:: fmt:: Formatter < ' _ > ) -> std:: fmt:: Result {
2031
+ match self {
2032
+ #[ cfg( any( target_os = "linux" , target_os = "freebsd" ) ) ]
2033
+ Self :: TooNegative => write ! ( f, "Passed a positive backlog less than -1" ) ,
2034
+ #[ cfg( not( any( target_os = "linux" , target_os = "freebsd" ) ) ) ]
2035
+ Self :: TooNegative => write ! ( f, "Passed a positive backlog less than 0" ) ,
2036
+ Self :: TooPositive => write ! ( f, "Passed a positive backlog greater than `{:?}`" , Backlog :: MAXCONN )
2037
+ }
2038
+ }
2039
+ }
2040
+
2041
+ impl std:: error:: Error for BacklogTryFromError { }
2042
+
2043
+ impl < T : Into < Backlog > > From < Option < T > > for Backlog {
2044
+ fn from ( backlog : Option < T > ) -> Self {
2045
+ backlog. map_or ( Self :: MAXCONN , |b| b. into ( ) )
2046
+ }
2047
+ }
2048
+
2049
+ impl From < u16 > for Backlog {
2050
+ fn from ( backlog : u16 ) -> Self {
2051
+ Self ( i32:: from ( backlog) )
2052
+ }
2053
+ }
2054
+
2055
+ impl From < u8 > for Backlog {
2056
+ fn from ( backlog : u8 ) -> Self {
2057
+ Self ( i32:: from ( backlog) )
2058
+ }
2059
+ }
2060
+
2061
+ impl From < Backlog > for i32 {
2062
+ fn from ( backlog : Backlog ) -> Self {
2063
+ backlog. 0
2064
+ }
2065
+ }
2066
+
2067
+ impl TryFrom < i64 > for Backlog {
2068
+ type Error = BacklogTryFromError ;
2069
+ fn try_from ( backlog : i64 ) -> std:: result:: Result < Self , Self :: Error > {
2070
+ match backlog {
2071
+ #[ cfg( any( target_os = "linux" , target_os = "freebsd" ) ) ]
2072
+ ..=-2 => Err ( BacklogTryFromError :: TooNegative ) ,
2073
+ #[ cfg( not( any( target_os = "linux" , target_os = "freebsd" ) ) ) ]
2074
+ ..=-1 => Err ( BacklogTryFromError :: TooNegative ) ,
2075
+ #[ cfg( any( target_os = "linux" , target_os = "freebsd" ) ) ]
2076
+ val if ( -1 ..=i64:: from ( Backlog :: MAXCONN . 0 ) ) . contains ( & val) => Ok ( Self ( i32:: try_from ( backlog) . map_err ( |_| BacklogTryFromError :: TooPositive ) ?) ) ,
2077
+ #[ cfg( not( any( target_os = "linux" , target_os = "freebsd" ) ) ) ]
2078
+ val if ( 0 ..=i64:: from ( Backlog :: MAXCONN . 0 ) ) . contains ( & val) => Ok ( Self ( i32:: try_from ( backlog) . map_err ( |_| BacklogTryFromError :: TooPositive ) ?) ) ,
2079
+ _ => Err ( BacklogTryFromError :: TooPositive ) ,
2080
+ }
2081
+ }
2082
+ }
2083
+
2084
+ impl TryFrom < i32 > for Backlog {
2085
+ type Error = BacklogTryFromError ;
2086
+ fn try_from ( backlog : i32 ) -> std:: result:: Result < Self , Self :: Error > {
2087
+ match backlog {
2088
+ #[ cfg( any( target_os = "linux" , target_os = "freebsd" ) ) ]
2089
+ ..=-2 => Err ( BacklogTryFromError :: TooNegative ) ,
2090
+ #[ cfg( not( any( target_os = "linux" , target_os = "freebsd" ) ) ) ]
2091
+ ..=-1 => Err ( BacklogTryFromError :: TooNegative ) ,
2092
+ #[ cfg( any( target_os = "linux" , target_os = "freebsd" ) ) ]
2093
+ val if ( -1 ..=Backlog :: MAXCONN . 0 ) . contains ( & val) => Ok ( Self ( backlog) ) ,
2094
+ #[ cfg( not( any( target_os = "linux" , target_os = "freebsd" ) ) ) ]
2095
+ val if ( 0 ..=Backlog :: MAXCONN . 0 ) . contains ( & val) => Ok ( Self ( backlog) ) ,
2096
+ _ => Err ( BacklogTryFromError :: TooPositive ) ,
2097
+ }
2098
+ }
2099
+ }
2100
+
2101
+ impl TryFrom < i16 > for Backlog {
2102
+ type Error = BacklogTryFromError ;
2103
+ fn try_from ( backlog : i16 ) -> std:: result:: Result < Self , Self :: Error > {
2104
+ match backlog {
2105
+ #[ cfg( any( target_os = "linux" , target_os = "freebsd" ) ) ]
2106
+ ..=-2 => Err ( BacklogTryFromError :: TooNegative ) ,
2107
+ #[ cfg( not( any( target_os = "linux" , target_os = "freebsd" ) ) ) ]
2108
+ ..=-1 => Err ( BacklogTryFromError :: TooNegative ) ,
2109
+ #[ cfg( any( target_os = "linux" , target_os = "freebsd" ) ) ]
2110
+ val if ( -1 ..=i16:: try_from ( Backlog :: MAXCONN . 0 ) . unwrap ( ) ) . contains ( & val) => Ok ( Self ( i32:: from ( backlog) ) ) ,
2111
+ #[ cfg( not( any( target_os = "linux" , target_os = "freebsd" ) ) ) ]
2112
+ val if ( 0 ..=i16:: try_from ( Backlog :: MAXCONN . 0 ) . unwrap ( ) ) . contains ( & val) => Ok ( Self ( i32:: from ( backlog) ) ) ,
2113
+ _ => Err ( BacklogTryFromError :: TooPositive ) ,
2114
+ }
2115
+ }
2116
+ }
2117
+
2118
+ impl TryFrom < i8 > for Backlog {
2119
+ type Error = BacklogTryFromError ;
2120
+ fn try_from ( backlog : i8 ) -> std:: result:: Result < Self , Self :: Error > {
2121
+ match backlog {
2122
+ ..=-2 => Err ( BacklogTryFromError :: TooNegative ) ,
2123
+ _ => Err ( BacklogTryFromError :: TooPositive ) ,
2124
+ }
2125
+ }
2126
+ }
2127
+
2128
+ /// Listen for connections on a socket
2129
+
2012
2130
/// Listen for connections on a socket
2013
2131
///
2014
2132
/// [Further reading](https://pubs.opengroup.org/onlinepubs/9699919799/functions/listen.html)
2015
- pub fn listen < F : AsFd > ( sock : & F , backlog : usize ) -> Result < ( ) > {
2133
+ pub fn listen < F : AsFd , B : Into < Backlog > > ( sock : & F , backlog : B ) -> Result < ( ) > {
2016
2134
let fd = sock. as_fd ( ) . as_raw_fd ( ) ;
2017
- let res = unsafe { libc:: listen ( fd, backlog as c_int ) } ;
2135
+ let res = unsafe { libc:: listen ( fd, i32 :: from ( backlog. into ( ) ) ) } ;
2018
2136
2019
2137
Errno :: result ( res) . map ( drop)
2020
2138
}
0 commit comments