@@ -10,6 +10,7 @@ use libc::{self, c_int, c_void, socklen_t};
1010use std:: ffi:: CString ;
1111use std:: ffi:: { CStr , OsStr , OsString } ;
1212use std:: mem:: { self , MaybeUninit } ;
13+ use std:: os:: fd:: OwnedFd ;
1314use std:: os:: unix:: ffi:: OsStrExt ;
1415#[ cfg( any( linux_android, target_os = "illumos" ) ) ]
1516use std:: os:: unix:: io:: { AsFd , AsRawFd } ;
@@ -192,6 +193,12 @@ macro_rules! sockopt_impl {
192193 $name, GetOnly , $level, $flag, usize , $crate:: sys:: socket:: sockopt:: GetUsize ) ;
193194 } ;
194195
196+ ( $( #[ $attr: meta] ) * $name: ident, GetOnly , $level: expr, $flag: path, OwnedFd ) =>
197+ {
198+ sockopt_impl!( $( #[ $attr] ) *
199+ $name, GetOnly , $level, $flag, OwnedFd , $crate:: sys:: socket:: sockopt:: GetOwnedFd ) ;
200+ } ;
201+
195202 ( $( #[ $attr: meta] ) * $name: ident, SetOnly , $level: expr, $flag: path, bool ) => {
196203 sockopt_impl!( $( #[ $attr] ) *
197204 $name, SetOnly , $level, $flag, bool , $crate:: sys:: socket:: sockopt:: SetBool ) ;
@@ -207,6 +214,12 @@ macro_rules! sockopt_impl {
207214 $name, SetOnly , $level, $flag, usize , $crate:: sys:: socket:: sockopt:: SetUsize ) ;
208215 } ;
209216
217+ ( $( #[ $attr: meta] ) * $name: ident, SetOnly , $level: expr, $flag: path, OwnedFd ) =>
218+ {
219+ sockopt_impl!( $( #[ $attr] ) *
220+ $name, SetOnly , $level, $flag, OwnedFd , $crate:: sys:: socket:: sockopt:: SetOwnedFd ) ;
221+ } ;
222+
210223 ( $( #[ $attr: meta] ) * $name: ident, Both , $level: expr, $flag: path, bool ) => {
211224 sockopt_impl!( $( #[ $attr] ) *
212225 $name, Both , $level, $flag, bool , $crate:: sys:: socket:: sockopt:: GetBool , $crate:: sys:: socket:: sockopt:: SetBool ) ;
@@ -222,6 +235,11 @@ macro_rules! sockopt_impl {
222235 $name, Both , $level, $flag, usize , $crate:: sys:: socket:: sockopt:: GetUsize , $crate:: sys:: socket:: sockopt:: SetUsize ) ;
223236 } ;
224237
238+ ( $( #[ $attr: meta] ) * $name: ident, Both , $level: expr, $flag: path, OwnedFd ) => {
239+ sockopt_impl!( $( #[ $attr] ) *
240+ $name, Both , $level, $flag, OwnedFd , $crate:: sys:: socket:: sockopt:: GetOwnedFd , $crate:: sys:: socket:: sockopt:: SetOwnedFd ) ;
241+ } ;
242+
225243 ( $( #[ $attr: meta] ) * $name: ident, Both , $level: expr, $flag: path,
226244 OsString <$array: ty>) =>
227245 {
@@ -662,6 +680,15 @@ sockopt_impl!(
662680 libc:: SO_PEERCRED ,
663681 super :: UnixCredentials
664682) ;
683+ #[ cfg( target_os = "linux" ) ]
684+ sockopt_impl ! (
685+ /// Return the pidfd of the foreign process connected to this socket.
686+ PeerPidfd ,
687+ GetOnly ,
688+ libc:: SOL_SOCKET ,
689+ libc:: SO_PEERPIDFD ,
690+ OwnedFd
691+ ) ;
665692#[ cfg( target_os = "freebsd" ) ]
666693#[ cfg( feature = "net" ) ]
667694sockopt_impl ! (
@@ -1804,6 +1831,68 @@ impl<'a> Set<'a, usize> for SetUsize {
18041831 }
18051832}
18061833
1834+
1835+ /// Getter for a `OwnedFd` value.
1836+ // Hide the docs, because it's an implementation detail of `sockopt_impl!`
1837+ #[ doc( hidden) ]
1838+ #[ derive( Clone , Copy , Debug ) ]
1839+ pub struct GetOwnedFd {
1840+ len : socklen_t ,
1841+ val : MaybeUninit < c_int > ,
1842+ }
1843+
1844+ impl Get < OwnedFd > for GetOwnedFd {
1845+ fn uninit ( ) -> Self {
1846+ GetOwnedFd {
1847+ len : mem:: size_of :: < c_int > ( ) as socklen_t ,
1848+ val : MaybeUninit :: uninit ( ) ,
1849+ }
1850+ }
1851+
1852+ fn ffi_ptr ( & mut self ) -> * mut c_void {
1853+ self . val . as_mut_ptr ( ) . cast ( )
1854+ }
1855+
1856+ fn ffi_len ( & mut self ) -> * mut socklen_t {
1857+ & mut self . len
1858+ }
1859+
1860+ unsafe fn assume_init ( self ) -> OwnedFd {
1861+ use std:: os:: fd:: { FromRawFd , RawFd } ;
1862+
1863+ assert_eq ! (
1864+ self . len as usize ,
1865+ mem:: size_of:: <c_int>( ) ,
1866+ "invalid getsockopt implementation"
1867+ ) ;
1868+ unsafe { OwnedFd :: from_raw_fd ( self . val . assume_init ( ) as RawFd ) }
1869+ }
1870+ }
1871+
1872+ /// Setter for an `OwnedFd` value.
1873+ // Hide the docs, because it's an implementation detail of `sockopt_impl!`
1874+ #[ doc( hidden) ]
1875+ #[ derive( Clone , Copy , Debug , Eq , PartialEq ) ]
1876+ pub struct SetOwnedFd {
1877+ val : c_int ,
1878+ }
1879+
1880+ impl < ' a > Set < ' a , OwnedFd > for SetOwnedFd {
1881+ fn new ( val : & ' a OwnedFd ) -> SetOwnedFd {
1882+ use std:: os:: fd:: AsRawFd ;
1883+
1884+ SetOwnedFd { val : val. as_raw_fd ( ) as c_int }
1885+ }
1886+
1887+ fn ffi_ptr ( & self ) -> * const c_void {
1888+ & self . val as * const c_int as * const c_void
1889+ }
1890+
1891+ fn ffi_len ( & self ) -> socklen_t {
1892+ mem:: size_of_val ( & self . val ) as socklen_t
1893+ }
1894+ }
1895+
18071896/// Getter for a `OsString` value.
18081897// Hide the docs, because it's an implementation detail of `sockopt_impl!`
18091898#[ doc( hidden) ]
0 commit comments