@@ -1552,23 +1552,23 @@ 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 ;
1563
1563
1564
1564
1565
1565
for ( i, ( ( slice, addr) , mmsghdr) ) in slices. into_iter( ) . zip( addrs. as_ref( ) ) . zip( data. items. iter_mut( ) ) . enumerate( ) {
1566
1566
let p = & mut mmsghdr. msg_hdr;
1567
- p. msg_iov = slice. as_ref( ) . as_ptr( ) as * mut libc :: iovec ;
1567
+ p. msg_iov = slice. as_ref( ) . as_ptr( ) . cast_mut ( ) . cast ( ) ;
1568
1568
p. msg_iovlen = slice. as_ref( ) . len( ) as _;
1569
1569
1570
1570
p. msg_namelen = addr. as_ref( ) . map_or( 0 , S :: len) ;
1571
- p. msg_name = addr. as_ref( ) . map_or( ptr:: null( ) , S :: as_ptr) as _ ;
1571
+ p. msg_name = addr. as_ref( ) . map_or( ptr:: null( ) , S :: as_ptr) . cast_mut ( ) . cast ( ) ;
1572
1572
1573
1573
// Encode each cmsg. This must happen after initializing the header because
1574
1574
// CMSG_NEXT_HDR and friends read the msg_control and msg_controllen fields.
@@ -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,
@@ -1743,16 +1757,14 @@ where
1743
1757
} )
1744
1758
}
1745
1759
1760
+ /// Iterator over results of [`recvmmsg`]/[`sendmmsg`]
1746
1761
#[ cfg( any(
1747
1762
target_os = "linux" ,
1748
1763
target_os = "android" ,
1749
1764
target_os = "freebsd" ,
1750
1765
target_os = "netbsd" ,
1751
1766
) ) ]
1752
1767
#[ derive( Debug ) ]
1753
- /// Iterator over results of [`recvmmsg`]/[`sendmmsg`]
1754
- ///
1755
- ///
1756
1768
pub struct MultiResults <' a, S > {
1757
1769
// preallocated structures
1758
1770
rmm: & ' a MultiHeaders <S >,
@@ -1903,7 +1915,7 @@ mod test {
1903
1915
1904
1916
let t = sys:: time:: TimeSpec :: from_duration( std:: time:: Duration :: from_secs( 10 ) ) ;
1905
1917
1906
- let recv = super :: recvmmsg( rsock. as_raw_fd( ) , & mut data, recv_iovs. iter ( ) , flags, Some ( t) ) ?;
1918
+ let recv = super :: recvmmsg( rsock. as_raw_fd( ) , & mut data, recv_iovs. iter_mut ( ) , flags, Some ( t) ) ?;
1907
1919
1908
1920
for rmsg in recv {
1909
1921
#[ cfg( not( any( qemu, target_arch = "aarch64" ) ) ) ]
0 commit comments