11use super :: { sockaddr_un, SocketAddr } ;
22use crate :: convert:: TryFrom ;
3+ use crate :: fmt;
34use crate :: io:: { self , IoSlice , IoSliceMut } ;
45use crate :: marker:: PhantomData ;
56use crate :: mem:: { size_of, zeroed, MaybeUninit } ;
@@ -84,28 +85,22 @@ fn add_to_ancillary_data<T>(
8485 source : & [ T ] ,
8586 cmsg_level : libc:: c_int ,
8687 cmsg_type : libc:: c_int ,
87- ) -> bool {
88- let source_len = if let Some ( source_len) = source. len ( ) . checked_mul ( size_of :: < T > ( ) ) {
89- if let Ok ( source_len) = u32:: try_from ( source_len) {
90- source_len
91- } else {
92- return false ;
93- }
94- } else {
95- return false ;
96- } ;
88+ ) -> Result < ( ) , AddAncillaryError > {
89+ let source_len =
90+ source. len ( ) . checked_mul ( size_of :: < T > ( ) ) . ok_or_else ( || AddAncillaryError :: new ( ) ) ?;
91+ let source_len = u32:: try_from ( source_len) . map_err ( |_| AddAncillaryError :: new ( ) ) ?;
9792
9893 unsafe {
9994 let additional_space = libc:: CMSG_SPACE ( source_len) as usize ;
10095
10196 let new_length = if let Some ( new_length) = additional_space. checked_add ( * length) {
10297 new_length
10398 } else {
104- return false ;
99+ return Err ( AddAncillaryError :: new ( ) ) ;
105100 } ;
106101
107102 if new_length > buffer. len ( ) {
108- return false ;
103+ return Err ( AddAncillaryError :: new ( ) ) ;
109104 }
110105
111106 buffer[ * length..new_length] . fill ( MaybeUninit :: new ( 0 ) ) ;
@@ -131,7 +126,7 @@ fn add_to_ancillary_data<T>(
131126 }
132127
133128 if previous_cmsg. is_null ( ) {
134- return false ;
129+ return Err ( AddAncillaryError :: new ( ) ) ;
135130 }
136131
137132 ( * previous_cmsg) . cmsg_level = cmsg_level;
@@ -142,7 +137,7 @@ fn add_to_ancillary_data<T>(
142137
143138 libc:: memcpy ( data, source. as_ptr ( ) . cast ( ) , source_len as usize ) ;
144139 }
145- true
140+ Ok ( ( ) )
146141}
147142
148143struct AncillaryDataIter < ' a , T > {
@@ -536,10 +531,9 @@ impl<'a> SocketAncillary<'a> {
536531
537532 /// Add file descriptors to the ancillary data.
538533 ///
539- /// The function returns `true` if there was enough space in the buffer.
540- /// If there was not enough space then no file descriptors was appended.
541- /// Technically, that means this operation adds a control message with the level `SOL_SOCKET`
542- /// and type `SCM_RIGHTS`.
534+ /// This operation adds a control message with the level `SOL_SOCKET` and type `SCM_RIGHTS`.
535+ /// If there is not enough space in the buffer for all file descriptors,
536+ /// an error is returned and no file descriptors are added.
543537 ///
544538 /// # Example
545539 ///
@@ -554,7 +548,7 @@ impl<'a> SocketAncillary<'a> {
554548 ///
555549 /// let mut ancillary_buffer = [0; 128];
556550 /// let mut ancillary = SocketAncillary::new(&mut ancillary_buffer[..]);
557- /// ancillary.add_fds(&[sock.as_raw_fd()][..]);
551+ /// ancillary.add_fds(&[sock.as_raw_fd()][..])? ;
558552 ///
559553 /// let mut buf = [1; 8];
560554 /// let mut bufs = &mut [IoSlice::new(&mut buf[..])][..];
@@ -563,7 +557,7 @@ impl<'a> SocketAncillary<'a> {
563557 /// }
564558 /// ```
565559 #[ unstable( feature = "unix_socket_ancillary_data" , issue = "76915" ) ]
566- pub fn add_fds ( & mut self , fds : & [ RawFd ] ) -> bool {
560+ pub fn add_fds ( & mut self , fds : & [ RawFd ] ) -> Result < ( ) , AddAncillaryError > {
567561 self . truncated = false ;
568562 add_to_ancillary_data (
569563 & mut self . buffer ,
@@ -576,14 +570,13 @@ impl<'a> SocketAncillary<'a> {
576570
577571 /// Add credentials to the ancillary data.
578572 ///
579- /// The function returns `true` if there was enough space in the buffer.
580- /// If there was not enough space then no credentials was appended.
581- /// Technically, that means this operation adds a control message with the level `SOL_SOCKET`
582- /// and type `SCM_CREDENTIALS` or `SCM_CREDS`.
583- ///
573+ /// This function adds a control message with the level `SOL_SOCKET`
574+ /// and type `SCM_CREDENTIALS` or `SCM_CREDS` (depending on the platform).
575+ /// If there is not enough space in the buffer for all credentials,
576+ /// an error is returned and no credentials are added.
584577 #[ cfg( any( doc, target_os = "android" , target_os = "linux" , ) ) ]
585578 #[ unstable( feature = "unix_socket_ancillary_data" , issue = "76915" ) ]
586- pub fn add_creds ( & mut self , creds : & [ SocketCred ] ) -> bool {
579+ pub fn add_creds ( & mut self , creds : & [ SocketCred ] ) -> Result < ( ) , AddAncillaryError > {
587580 self . truncated = false ;
588581 add_to_ancillary_data (
589582 & mut self . buffer ,
@@ -642,3 +635,40 @@ impl<'a> SocketAncillary<'a> {
642635 self . truncated = false ;
643636 }
644637}
638+
639+ /// An error returned when trying to add anciallary data that exceeds the buffer capacity.
640+ #[ cfg( any( doc, target_os = "android" , target_os = "linux" , ) ) ]
641+ #[ unstable( feature = "unix_socket_ancillary_data" , issue = "76915" ) ]
642+ pub struct AddAncillaryError {
643+ _priv : ( ) ,
644+ }
645+
646+ impl AddAncillaryError {
647+ fn new ( ) -> Self {
648+ Self { _priv : ( ) }
649+ }
650+ }
651+
652+ #[ unstable( feature = "unix_socket_ancillary_data" , issue = "76915" ) ]
653+ impl fmt:: Debug for AddAncillaryError {
654+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
655+ f. debug_struct ( "AddAncillaryError" ) . finish ( )
656+ }
657+ }
658+
659+ #[ unstable( feature = "unix_socket_ancillary_data" , issue = "76915" ) ]
660+ impl fmt:: Display for AddAncillaryError {
661+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
662+ write ! ( f, "could not add data to anciallary buffer" )
663+ }
664+ }
665+
666+ #[ unstable( feature = "unix_socket_ancillary_data" , issue = "76915" ) ]
667+ impl crate :: error:: Error for AddAncillaryError { }
668+
669+ #[ unstable( feature = "unix_socket_ancillary_data" , issue = "76915" ) ]
670+ impl From < AddAncillaryError > for io:: Error {
671+ fn from ( other : AddAncillaryError ) -> Self {
672+ Self :: new ( io:: ErrorKind :: Other , other)
673+ }
674+ }
0 commit comments