@@ -86,7 +86,12 @@ fn add_to_ancillary_data<T>(
8686 cmsg_level : libc:: c_int ,
8787 cmsg_type : libc:: c_int ,
8888) -> bool {
89- let source_len = if let Some ( source_len) = source. len ( ) . checked_mul ( size_of :: < T > ( ) ) {
89+ #[ cfg( not( target_os = "freebsd" ) ) ]
90+ let cmsg_size = source. len ( ) . checked_mul ( size_of :: < T > ( ) ) ;
91+ #[ cfg( target_os = "freebsd" ) ]
92+ let cmsg_size = Some ( unsafe { libc:: SOCKCRED2SIZE ( 1 ) } ) ;
93+
94+ let source_len = if let Some ( source_len) = cmsg_size {
9095 if let Ok ( source_len) = u32:: try_from ( source_len) {
9196 source_len
9297 } else {
@@ -178,7 +183,13 @@ impl<'a, T> Iterator for AncillaryDataIter<'a, T> {
178183 }
179184}
180185
181- #[ cfg( all( doc, not( target_os = "android" ) , not( target_os = "linux" ) , not( target_os = "netbsd" ) ) ) ]
186+ #[ cfg( all(
187+ doc,
188+ not( target_os = "android" ) ,
189+ not( target_os = "linux" ) ,
190+ not( target_os = "netbsd" ) ,
191+ not( target_os = "freebsd" )
192+ ) ) ]
182193#[ unstable( feature = "unix_socket_ancillary_data" , issue = "76915" ) ]
183194#[ derive( Clone ) ]
184195pub struct SocketCred ( ( ) ) ;
@@ -194,6 +205,11 @@ pub struct SocketCred(libc::ucred);
194205#[ derive( Clone ) ]
195206pub struct SocketCred ( libc:: sockcred ) ;
196207
208+ #[ cfg( target_os = "freebsd" ) ]
209+ #[ unstable( feature = "unix_socket_ancillary_data" , issue = "76915" ) ]
210+ #[ derive( Clone ) ]
211+ pub struct SocketCred ( libc:: sockcred2 ) ;
212+
197213#[ doc( cfg( any( target_os = "android" , target_os = "linux" ) ) ) ]
198214#[ cfg( any( target_os = "android" , target_os = "linux" ) ) ]
199215impl SocketCred {
@@ -246,6 +262,66 @@ impl SocketCred {
246262 }
247263}
248264
265+ #[ cfg( target_os = "freebsd" ) ]
266+ impl SocketCred {
267+ /// Create a Unix credential struct.
268+ ///
269+ /// PID, UID and GID is set to 0.
270+ #[ unstable( feature = "unix_socket_ancillary_data" , issue = "76915" ) ]
271+ #[ must_use]
272+ pub fn new ( ) -> SocketCred {
273+ SocketCred ( libc:: sockcred2 {
274+ sc_version : 0 ,
275+ sc_pid : 0 ,
276+ sc_uid : 0 ,
277+ sc_euid : 0 ,
278+ sc_gid : 0 ,
279+ sc_egid : 0 ,
280+ sc_ngroups : 0 ,
281+ sc_groups : [ 0 ; 1 ] ,
282+ } )
283+ }
284+
285+ /// Set the PID.
286+ #[ unstable( feature = "unix_socket_ancillary_data" , issue = "76915" ) ]
287+ pub fn set_pid ( & mut self , pid : libc:: pid_t ) {
288+ self . 0 . sc_pid = pid;
289+ }
290+
291+ /// Get the current PID.
292+ #[ must_use]
293+ #[ unstable( feature = "unix_socket_ancillary_data" , issue = "76915" ) ]
294+ pub fn get_pid ( & self ) -> libc:: pid_t {
295+ self . 0 . sc_pid
296+ }
297+
298+ /// Set the UID.
299+ #[ unstable( feature = "unix_socket_ancillary_data" , issue = "76915" ) ]
300+ pub fn set_uid ( & mut self , uid : libc:: uid_t ) {
301+ self . 0 . sc_euid = uid;
302+ }
303+
304+ /// Get the current UID.
305+ #[ must_use]
306+ #[ unstable( feature = "unix_socket_ancillary_data" , issue = "76915" ) ]
307+ pub fn get_uid ( & self ) -> libc:: uid_t {
308+ self . 0 . sc_euid
309+ }
310+
311+ /// Set the GID.
312+ #[ unstable( feature = "unix_socket_ancillary_data" , issue = "76915" ) ]
313+ pub fn set_gid ( & mut self , gid : libc:: gid_t ) {
314+ self . 0 . sc_egid = gid;
315+ }
316+
317+ /// Get the current GID.
318+ #[ must_use]
319+ #[ unstable( feature = "unix_socket_ancillary_data" , issue = "76915" ) ]
320+ pub fn get_gid ( & self ) -> libc:: gid_t {
321+ self . 0 . sc_egid
322+ }
323+ }
324+
249325#[ cfg( target_os = "netbsd" ) ]
250326impl SocketCred {
251327 /// Create a Unix credential struct.
@@ -271,6 +347,7 @@ impl SocketCred {
271347 }
272348
273349 /// Get the current PID.
350+ #[ must_use]
274351 #[ unstable( feature = "unix_socket_ancillary_data" , issue = "76915" ) ]
275352 pub fn get_pid ( & self ) -> libc:: pid_t {
276353 self . 0 . sc_pid
@@ -283,6 +360,7 @@ impl SocketCred {
283360 }
284361
285362 /// Get the current UID.
363+ #[ must_use]
286364 #[ unstable( feature = "unix_socket_ancillary_data" , issue = "76915" ) ]
287365 pub fn get_uid ( & self ) -> libc:: uid_t {
288366 self . 0 . sc_uid
@@ -295,6 +373,7 @@ impl SocketCred {
295373 }
296374
297375 /// Get the current GID.
376+ #[ must_use]
298377 #[ unstable( feature = "unix_socket_ancillary_data" , issue = "76915" ) ]
299378 pub fn get_gid ( & self ) -> libc:: gid_t {
300379 self . 0 . sc_gid
@@ -316,7 +395,13 @@ impl<'a> Iterator for ScmRights<'a> {
316395 }
317396}
318397
319- #[ cfg( all( doc, not( target_os = "android" ) , not( target_os = "linux" ) , not( target_os = "netbsd" ) ) ) ]
398+ #[ cfg( all(
399+ doc,
400+ not( target_os = "android" ) ,
401+ not( target_os = "linux" ) ,
402+ not( target_os = "netbsd" ) ,
403+ not( target_os = "freebsd" )
404+ ) ) ]
320405#[ unstable( feature = "unix_socket_ancillary_data" , issue = "76915" ) ]
321406pub struct ScmCredentials < ' a > ( AncillaryDataIter < ' a , ( ) > ) ;
322407
@@ -327,11 +412,21 @@ pub struct ScmCredentials<'a>(AncillaryDataIter<'a, ()>);
327412#[ unstable( feature = "unix_socket_ancillary_data" , issue = "76915" ) ]
328413pub struct ScmCredentials < ' a > ( AncillaryDataIter < ' a , libc:: ucred > ) ;
329414
415+ #[ cfg( target_os = "freebsd" ) ]
416+ #[ unstable( feature = "unix_socket_ancillary_data" , issue = "76915" ) ]
417+ pub struct ScmCredentials < ' a > ( AncillaryDataIter < ' a , libc:: sockcred2 > ) ;
418+
330419#[ cfg( target_os = "netbsd" ) ]
331420#[ unstable( feature = "unix_socket_ancillary_data" , issue = "76915" ) ]
332421pub struct ScmCredentials < ' a > ( AncillaryDataIter < ' a , libc:: sockcred > ) ;
333422
334- #[ cfg( any( doc, target_os = "android" , target_os = "linux" , target_os = "netbsd" , ) ) ]
423+ #[ cfg( any(
424+ doc,
425+ target_os = "android" ,
426+ target_os = "linux" ,
427+ target_os = "netbsd" ,
428+ target_os = "freebsd"
429+ ) ) ]
335430#[ unstable( feature = "unix_socket_ancillary_data" , issue = "76915" ) ]
336431impl < ' a > Iterator for ScmCredentials < ' a > {
337432 type Item = SocketCred ;
@@ -353,7 +448,13 @@ pub enum AncillaryError {
353448#[ unstable( feature = "unix_socket_ancillary_data" , issue = "76915" ) ]
354449pub enum AncillaryData < ' a > {
355450 ScmRights ( ScmRights < ' a > ) ,
356- #[ cfg( any( doc, target_os = "android" , target_os = "linux" , target_os = "netbsd" , ) ) ]
451+ #[ cfg( any(
452+ doc,
453+ target_os = "android" ,
454+ target_os = "linux" ,
455+ target_os = "netbsd" ,
456+ target_os = "freebsd"
457+ ) ) ]
357458 ScmCredentials ( ScmCredentials < ' a > ) ,
358459}
359460
@@ -376,7 +477,13 @@ impl<'a> AncillaryData<'a> {
376477 ///
377478 /// `data` must contain a valid control message and the control message must be type of
378479 /// `SOL_SOCKET` and level of `SCM_CREDENTIALS` or `SCM_CREDS`.
379- #[ cfg( any( doc, target_os = "android" , target_os = "linux" , target_os = "netbsd" , ) ) ]
480+ #[ cfg( any(
481+ doc,
482+ target_os = "android" ,
483+ target_os = "linux" ,
484+ target_os = "netbsd" ,
485+ target_os = "freebsd"
486+ ) ) ]
380487 unsafe fn as_credentials ( data : & ' a [ u8 ] ) -> Self {
381488 let ancillary_data_iter = AncillaryDataIter :: new ( data) ;
382489 let scm_credentials = ScmCredentials ( ancillary_data_iter) ;
@@ -395,6 +502,8 @@ impl<'a> AncillaryData<'a> {
395502 libc:: SCM_RIGHTS => Ok ( AncillaryData :: as_rights ( data) ) ,
396503 #[ cfg( any( target_os = "android" , target_os = "linux" , ) ) ]
397504 libc:: SCM_CREDENTIALS => Ok ( AncillaryData :: as_credentials ( data) ) ,
505+ #[ cfg( target_os = "freebsd" ) ]
506+ libc:: SCM_CREDS2 => Ok ( AncillaryData :: as_credentials ( data) ) ,
398507 #[ cfg( target_os = "netbsd" ) ]
399508 libc:: SCM_CREDS => Ok ( AncillaryData :: as_credentials ( data) ) ,
400509 cmsg_type => {
@@ -603,12 +712,18 @@ impl<'a> SocketAncillary<'a> {
603712
604713 /// Add credentials to the ancillary data.
605714 ///
606- /// The function returns `true` if there was enough space in the buffer.
607- /// If there was not enough space then no credentials was appended.
715+ /// The function returns `true` if there is enough space in the buffer.
716+ /// If there is not enough space then no credentials will be appended.
608717 /// Technically, that means this operation adds a control message with the level `SOL_SOCKET`
609- /// and type `SCM_CREDENTIALS` or `SCM_CREDS`.
610- ///
611- #[ cfg( any( doc, target_os = "android" , target_os = "linux" , target_os = "netbsd" , ) ) ]
718+ /// and type `SCM_CREDENTIALS`, `SCM_CREDS`, or `SCM_CREDS2`.
719+ ///
720+ #[ cfg( any(
721+ doc,
722+ target_os = "android" ,
723+ target_os = "linux" ,
724+ target_os = "netbsd" ,
725+ target_os = "freebsd"
726+ ) ) ]
612727 #[ unstable( feature = "unix_socket_ancillary_data" , issue = "76915" ) ]
613728 pub fn add_creds ( & mut self , creds : & [ SocketCred ] ) -> bool {
614729 self . truncated = false ;
@@ -617,8 +732,10 @@ impl<'a> SocketAncillary<'a> {
617732 & mut self . length ,
618733 creds,
619734 libc:: SOL_SOCKET ,
620- #[ cfg( not( target_os = "netbsd" ) ) ]
735+ #[ cfg( not( any ( target_os = "netbsd" , target_os = "freebsd" ) ) ) ]
621736 libc:: SCM_CREDENTIALS ,
737+ #[ cfg( target_os = "freebsd" ) ]
738+ libc:: SCM_CREDS2 ,
622739 #[ cfg( target_os = "netbsd" ) ]
623740 libc:: SCM_CREDS ,
624741 )
0 commit comments