55use crate :: backend:: { self , c} ;
66use crate :: fd:: { AsFd , BorrowedFd , OwnedFd } ;
77use crate :: io:: { self , IoSlice , IoSliceMut } ;
8+ #[ cfg( linux_kernel) ]
9+ use crate :: net:: UCred ;
810
911use core:: iter:: FusedIterator ;
1012use core:: marker:: PhantomData ;
@@ -22,6 +24,11 @@ macro_rules! cmsg_space {
2224 $len * :: core:: mem:: size_of:: <$crate:: fd:: BorrowedFd <' static >>( ) ,
2325 )
2426 } ;
27+ ( ScmCredentials ( $len: expr) ) => {
28+ $crate:: net:: __cmsg_space(
29+ $len * :: core:: mem:: size_of:: <$crate:: net:: UCred >( ) ,
30+ )
31+ } ;
2532
2633 // Combo Rules
2734 ( ( $( $( $x: tt) * ) ,+) ) => {
@@ -43,6 +50,9 @@ pub fn __cmsg_space(len: usize) -> usize {
4350pub enum SendAncillaryMessage < ' slice , ' fd > {
4451 /// Send file descriptors.
4552 ScmRights ( & ' slice [ BorrowedFd < ' fd > ] ) ,
53+ /// Send process credentials.
54+ #[ cfg( linux_kernel) ]
55+ ScmCredentials ( UCred ) ,
4656}
4757
4858impl SendAncillaryMessage < ' _ , ' _ > {
@@ -52,6 +62,8 @@ impl SendAncillaryMessage<'_, '_> {
5262 pub fn size ( & self ) -> usize {
5363 let total_bytes = match self {
5464 Self :: ScmRights ( slice) => size_of_val ( * slice) ,
65+ #[ cfg( linux_kernel) ]
66+ Self :: ScmCredentials ( ucred) => size_of_val ( ucred) ,
5567 } ;
5668
5769 unsafe {
@@ -69,6 +81,9 @@ impl SendAncillaryMessage<'_, '_> {
6981pub enum RecvAncillaryMessage < ' a > {
7082 /// Received file descriptors.
7183 ScmRights ( AncillaryIter < ' a , OwnedFd > ) ,
84+ /// Received process credentials.
85+ #[ cfg( linux_kernel) ]
86+ ScmCredentials ( UCred ) ,
7287}
7388
7489/// Buffer for sending ancillary messages with [`sendmsg`], [`sendmsg_v4`],
@@ -139,6 +154,13 @@ impl<'buf, 'slice, 'fd> SendAncillaryBuffer<'buf, 'slice, 'fd> {
139154 unsafe { slice:: from_raw_parts ( fds. as_ptr ( ) . cast :: < u8 > ( ) , size_of_val ( fds) ) } ;
140155 self . push_ancillary ( fds_bytes, c:: SOL_SOCKET as _ , c:: SCM_RIGHTS as _ )
141156 }
157+ #[ cfg( linux_kernel) ]
158+ SendAncillaryMessage :: ScmCredentials ( ucred) => {
159+ let ucred_bytes = unsafe {
160+ slice:: from_raw_parts ( & ucred as * const _ as * const u8 , size_of_val ( & ucred) )
161+ } ;
162+ self . push_ancillary ( ucred_bytes, c:: SOL_SOCKET as _ , c:: SCM_CREDENTIALS as _ )
163+ }
142164 }
143165 }
144166
@@ -316,6 +338,15 @@ impl<'buf> AncillaryDrain<'buf> {
316338
317339 Some ( RecvAncillaryMessage :: ScmRights ( fds) )
318340 }
341+ #[ cfg( linux_kernel) ]
342+ ( c:: SOL_SOCKET , c:: SCM_CREDENTIALS ) => {
343+ if payload_len >= size_of :: < UCred > ( ) {
344+ let ucred = payload. as_ptr ( ) . cast :: < UCred > ( ) . read_unaligned ( ) ;
345+ Some ( RecvAncillaryMessage :: ScmCredentials ( ucred) )
346+ } else {
347+ None
348+ }
349+ }
319350 _ => None ,
320351 }
321352 }
0 commit comments