@@ -10,6 +10,7 @@ use libc::{self, c_int, c_void, socklen_t};
10
10
use std:: ffi:: CString ;
11
11
use std:: ffi:: { CStr , OsStr , OsString } ;
12
12
use std:: mem:: { self , MaybeUninit } ;
13
+ use std:: os:: fd:: OwnedFd ;
13
14
use std:: os:: unix:: ffi:: OsStrExt ;
14
15
#[ cfg( any( linux_android, target_os = "illumos" ) ) ]
15
16
use std:: os:: unix:: io:: { AsFd , AsRawFd } ;
@@ -192,6 +193,12 @@ macro_rules! sockopt_impl {
192
193
$name, GetOnly , $level, $flag, usize , $crate:: sys:: socket:: sockopt:: GetUsize ) ;
193
194
} ;
194
195
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
+
195
202
( $( #[ $attr: meta] ) * $name: ident, SetOnly , $level: expr, $flag: path, bool ) => {
196
203
sockopt_impl!( $( #[ $attr] ) *
197
204
$name, SetOnly , $level, $flag, bool , $crate:: sys:: socket:: sockopt:: SetBool ) ;
@@ -207,6 +214,12 @@ macro_rules! sockopt_impl {
207
214
$name, SetOnly , $level, $flag, usize , $crate:: sys:: socket:: sockopt:: SetUsize ) ;
208
215
} ;
209
216
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
+
210
223
( $( #[ $attr: meta] ) * $name: ident, Both , $level: expr, $flag: path, bool ) => {
211
224
sockopt_impl!( $( #[ $attr] ) *
212
225
$name, Both , $level, $flag, bool , $crate:: sys:: socket:: sockopt:: GetBool , $crate:: sys:: socket:: sockopt:: SetBool ) ;
@@ -222,6 +235,11 @@ macro_rules! sockopt_impl {
222
235
$name, Both , $level, $flag, usize , $crate:: sys:: socket:: sockopt:: GetUsize , $crate:: sys:: socket:: sockopt:: SetUsize ) ;
223
236
} ;
224
237
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
+
225
243
( $( #[ $attr: meta] ) * $name: ident, Both , $level: expr, $flag: path,
226
244
OsString <$array: ty>) =>
227
245
{
@@ -662,6 +680,15 @@ sockopt_impl!(
662
680
libc:: SO_PEERCRED ,
663
681
super :: UnixCredentials
664
682
) ;
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
+ ) ;
665
692
#[ cfg( target_os = "freebsd" ) ]
666
693
#[ cfg( feature = "net" ) ]
667
694
sockopt_impl ! (
@@ -1804,6 +1831,68 @@ impl<'a> Set<'a, usize> for SetUsize {
1804
1831
}
1805
1832
}
1806
1833
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
+
1807
1896
/// Getter for a `OsString` value.
1808
1897
// Hide the docs, because it's an implementation detail of `sockopt_impl!`
1809
1898
#[ doc( hidden) ]
0 commit comments