@@ -1552,11 +1552,11 @@ pub fn sendmmsg<'a, XS, AS, C, I, S>(
1552
1552
flags: MsgFlags
1553
1553
) -> crate :: Result <MultiResults <' a, S >>
1554
1554
where
1555
- XS : IntoIterator <Item = & ' a I >,
1555
+ XS : IntoIterator <Item = I >,
1556
1556
AS : AsRef <[ Option <S >] >,
1557
- I : AsRef <[ IoSlice <' a>] > + ' a ,
1558
- C : AsRef <[ ControlMessage <' a>] > + ' a ,
1559
- S : SockaddrLike + ' a
1557
+ I : AsRef <[ IoSlice <' a>] >,
1558
+ C : AsRef <[ ControlMessage <' a>] >,
1559
+ S : SockaddrLike ,
1560
1560
{
1561
1561
1562
1562
let mut count = 0 ;
@@ -1583,9 +1583,16 @@ pub fn sendmmsg<'a, XS, AS, C, I, S>(
1583
1583
pmhdr = unsafe { CMSG_NXTHDR ( p, pmhdr) } ;
1584
1584
}
1585
1585
1586
- count = i+1 ;
1586
+ // Doing an unchecked addition is alright here, as the only way to obtain an instance of `MultiHeaders`
1587
+ // is through the `preallocate` function, which takes an `usize` as an argument to define its size,
1588
+ // which also provides an upper bound for the size of this zipped iterator. Thus, `i < usize::MAX` or in
1589
+ // other words: `count` doesn't overflow
1590
+ count = i + 1 ;
1587
1591
}
1588
1592
1593
+ // SAFETY: all pointers are guaranteed to be valid for the scope of this function. `count` does represent the
1594
+ // maximum number of messages that can be sent safely (i.e. `count` is the minimum of the sizes of `slices`,
1595
+ // `data.items` and `addrs`)
1589
1596
let sent = Errno :: result( unsafe {
1590
1597
libc:: sendmmsg(
1591
1598
fd,
@@ -1711,21 +1718,28 @@ pub fn recvmmsg<'a, XS, S, I>(
1711
1718
mut timeout: Option <crate :: sys:: time:: TimeSpec >,
1712
1719
) -> crate :: Result <MultiResults <' a, S >>
1713
1720
where
1714
- XS : IntoIterator <Item = & ' a I >,
1715
- I : AsRef <[ IoSliceMut <' a>] > + ' a ,
1721
+ XS : IntoIterator <Item = I >,
1722
+ I : AsMut <[ IoSliceMut <' a>] >,
1716
1723
{
1717
1724
let mut count = 0 ;
1718
- for ( i, ( slice, mmsghdr) ) in slices. into_iter( ) . zip( data. items. iter_mut( ) ) . enumerate( ) {
1725
+ for ( i, ( mut slice, mmsghdr) ) in slices. into_iter( ) . zip( data. items. iter_mut( ) ) . enumerate( ) {
1719
1726
let p = & mut mmsghdr. msg_hdr;
1720
- p. msg_iov = slice. as_ref( ) . as_ptr( ) as * mut libc:: iovec;
1721
- p. msg_iovlen = slice. as_ref( ) . len( ) as _;
1727
+ p. msg_iov = slice. as_mut( ) . as_mut_ptr( ) . cast( ) ;
1728
+ p. msg_iovlen = slice. as_mut( ) . len( ) as _;
1729
+
1730
+ // Doing an unchecked addition is alright here, as the only way to obtain an instance of `MultiHeaders`
1731
+ // is through the `preallocate` function, which takes an `usize` as an argument to define its size,
1732
+ // which also provides an upper bound for the size of this zipped iterator. Thus, `i < usize::MAX` or in
1733
+ // other words: `count` doesn't overflow
1722
1734
count = i + 1 ;
1723
1735
}
1724
1736
1725
1737
let timeout_ptr = timeout
1726
1738
. as_mut( )
1727
1739
. map_or_else( std:: ptr:: null_mut, |t| t as * mut _ as * mut libc:: timespec) ;
1728
1740
1741
+ // SAFETY: all pointers are guaranteed to be valid for the scope of this function. `count` does represent the
1742
+ // maximum number of messages that can be received safely (i.e. `count` is the minimum of the sizes of `slices` and `data.items`)
1729
1743
let received = Errno :: result( unsafe {
1730
1744
libc:: recvmmsg(
1731
1745
fd,
@@ -1903,7 +1917,7 @@ mod test {
1903
1917
1904
1918
let t = sys:: time:: TimeSpec :: from_duration( std:: time:: Duration :: from_secs( 10 ) ) ;
1905
1919
1906
- let recv = super :: recvmmsg( rsock. as_raw_fd( ) , & mut data, recv_iovs. iter ( ) , flags, Some ( t) ) ?;
1920
+ let recv = super :: recvmmsg( rsock. as_raw_fd( ) , & mut data, recv_iovs. iter_mut ( ) , flags, Some ( t) ) ?;
1907
1921
1908
1922
for rmsg in recv {
1909
1923
#[ cfg( not( any( qemu, target_arch = "aarch64" ) ) ) ]
0 commit comments