MCPcopy Index your code
hub / github.com/RustPython/RustPython / pack_cmsgs_to_send

Method pack_cmsgs_to_send

crates/stdlib/src/socket.rs:2117–2168  ·  view source on GitHub ↗
(
            cmsgs: &[(i32, i32, ArgBytesLike)],
            vm: &VirtualMachine,
        )

Source from the content-addressed store, hash-verified

2115 // based on nix's implementation
2116 #[cfg(all(unix, not(target_os = "redox")))]
2117 fn pack_cmsgs_to_send(
2118 cmsgs: &[(i32, i32, ArgBytesLike)],
2119 vm: &VirtualMachine,
2120 ) -> PyResult<Vec<u8>> {
2121 use core::{mem, ptr};
2122
2123 if cmsgs.is_empty() {
2124 return Ok(vec![]);
2125 }
2126
2127 let capacity = cmsgs
2128 .iter()
2129 .map(|(_, _, buf)| buf.len())
2130 .try_fold(0, |sum, len| {
2131 let space = checked_cmsg_space(len).ok_or_else(|| {
2132 vm.new_os_error("ancillary data item too large".to_owned())
2133 })?;
2134 usize::checked_add(sum, space)
2135 .ok_or_else(|| vm.new_os_error("too much ancillary data".to_owned()))
2136 })?;
2137
2138 let mut cmsg_buffer = vec![0u8; capacity];
2139
2140 // make a dummy msghdr so we can use the CMSG_* apis
2141 let mut mhdr = unsafe { mem::zeroed::<libc::msghdr>() };
2142 mhdr.msg_control = cmsg_buffer.as_mut_ptr().cast();
2143 mhdr.msg_controllen = capacity as _;
2144
2145 let mut pmhdr: *mut libc::cmsghdr = unsafe { libc::CMSG_FIRSTHDR(&mhdr) };
2146 for (lvl, typ, buf) in cmsgs {
2147 if pmhdr.is_null() {
2148 return Err(vm.new_runtime_error(
2149 "unexpected NULL result from CMSG_FIRSTHDR/CMSG_NXTHDR",
2150 ));
2151 }
2152 let data = &*buf.borrow_buf();
2153 assert_eq!(data.len(), buf.len());
2154 // Safe because we know that pmhdr is valid, and we initialized it with
2155 // sufficient space
2156 unsafe {
2157 (*pmhdr).cmsg_level = *lvl;
2158 (*pmhdr).cmsg_type = *typ;
2159 (*pmhdr).cmsg_len = libc::CMSG_LEN(data.len() as _) as _;
2160 ptr::copy_nonoverlapping(data.as_ptr(), libc::CMSG_DATA(pmhdr), data.len());
2161 }
2162
2163 // Safe because mhdr is valid
2164 pmhdr = unsafe { libc::CMSG_NXTHDR(&mhdr, pmhdr) };
2165 }
2166
2167 Ok(cmsg_buffer)
2168 }
2169
2170 #[pymethod]
2171 fn close(&self) -> io::Result<()> {

Callers

nothing calls this directly

Calls 13

checked_cmsg_spaceFunction · 0.85
ok_or_elseMethod · 0.80
new_os_errorMethod · 0.80
as_mut_ptrMethod · 0.80
ErrClass · 0.50
is_emptyMethod · 0.45
mapMethod · 0.45
iterMethod · 0.45
lenMethod · 0.45
to_ownedMethod · 0.45
castMethod · 0.45
borrow_bufMethod · 0.45

Tested by

no test coverage detected