1
1
use super :: { sockaddr_un, SocketAddr } ;
2
2
use crate :: convert:: TryFrom ;
3
+ use crate :: fmt;
3
4
use crate :: io:: { self , IoSlice , IoSliceMut } ;
4
5
use crate :: marker:: PhantomData ;
5
6
use crate :: mem:: { size_of, zeroed, MaybeUninit } ;
@@ -84,28 +85,22 @@ fn add_to_ancillary_data<T>(
84
85
source : & [ T ] ,
85
86
cmsg_level : libc:: c_int ,
86
87
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 ( ) ) ?;
97
92
98
93
unsafe {
99
94
let additional_space = libc:: CMSG_SPACE ( source_len) as usize ;
100
95
101
96
let new_length = if let Some ( new_length) = additional_space. checked_add ( * length) {
102
97
new_length
103
98
} else {
104
- return false ;
99
+ return Err ( AddAncillaryError :: new ( ) ) ;
105
100
} ;
106
101
107
102
if new_length > buffer. len ( ) {
108
- return false ;
103
+ return Err ( AddAncillaryError :: new ( ) ) ;
109
104
}
110
105
111
106
buffer[ * length..new_length] . fill ( MaybeUninit :: new ( 0 ) ) ;
@@ -131,7 +126,7 @@ fn add_to_ancillary_data<T>(
131
126
}
132
127
133
128
if previous_cmsg. is_null ( ) {
134
- return false ;
129
+ return Err ( AddAncillaryError :: new ( ) ) ;
135
130
}
136
131
137
132
( * previous_cmsg) . cmsg_level = cmsg_level;
@@ -142,7 +137,7 @@ fn add_to_ancillary_data<T>(
142
137
143
138
libc:: memcpy ( data, source. as_ptr ( ) . cast ( ) , source_len as usize ) ;
144
139
}
145
- true
140
+ Ok ( ( ) )
146
141
}
147
142
148
143
struct AncillaryDataIter < ' a , T > {
@@ -536,10 +531,9 @@ impl<'a> SocketAncillary<'a> {
536
531
537
532
/// Add file descriptors to the ancillary data.
538
533
///
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.
543
537
///
544
538
/// # Example
545
539
///
@@ -554,7 +548,7 @@ impl<'a> SocketAncillary<'a> {
554
548
///
555
549
/// let mut ancillary_buffer = [0; 128];
556
550
/// let mut ancillary = SocketAncillary::new(&mut ancillary_buffer[..]);
557
- /// ancillary.add_fds(&[sock.as_raw_fd()][..]);
551
+ /// ancillary.add_fds(&[sock.as_raw_fd()][..])? ;
558
552
///
559
553
/// let mut buf = [1; 8];
560
554
/// let mut bufs = &mut [IoSlice::new(&mut buf[..])][..];
@@ -563,7 +557,7 @@ impl<'a> SocketAncillary<'a> {
563
557
/// }
564
558
/// ```
565
559
#[ 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 > {
567
561
self . truncated = false ;
568
562
add_to_ancillary_data (
569
563
& mut self . buffer ,
@@ -576,14 +570,13 @@ impl<'a> SocketAncillary<'a> {
576
570
577
571
/// Add credentials to the ancillary data.
578
572
///
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.
584
577
#[ cfg( any( doc, target_os = "android" , target_os = "linux" , ) ) ]
585
578
#[ 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 > {
587
580
self . truncated = false ;
588
581
add_to_ancillary_data (
589
582
& mut self . buffer ,
@@ -642,3 +635,40 @@ impl<'a> SocketAncillary<'a> {
642
635
self . truncated = false ;
643
636
}
644
637
}
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