(
&self,
bufsize: isize,
ancbufsize: OptionalArg<isize>,
flags: OptionalArg<i32>,
vm: &VirtualMachine,
)
| 1994 | #[cfg(all(unix, not(target_os = "redox")))] |
| 1995 | #[pymethod] |
| 1996 | fn recvmsg( |
| 1997 | &self, |
| 1998 | bufsize: isize, |
| 1999 | ancbufsize: OptionalArg<isize>, |
| 2000 | flags: OptionalArg<i32>, |
| 2001 | vm: &VirtualMachine, |
| 2002 | ) -> PyResult<PyTupleRef> { |
| 2003 | use core::mem::MaybeUninit; |
| 2004 | |
| 2005 | if bufsize < 0 { |
| 2006 | return Err(vm.new_value_error("negative buffer size in recvmsg")); |
| 2007 | } |
| 2008 | let bufsize = bufsize as usize; |
| 2009 | |
| 2010 | let ancbufsize = ancbufsize.unwrap_or(0); |
| 2011 | if ancbufsize < 0 { |
| 2012 | return Err(vm.new_value_error("negative ancillary buffer size in recvmsg")); |
| 2013 | } |
| 2014 | let ancbufsize = ancbufsize as usize; |
| 2015 | let flags = flags.unwrap_or(0); |
| 2016 | |
| 2017 | // Allocate buffers |
| 2018 | let mut data_buf: Vec<MaybeUninit<u8>> = vec![MaybeUninit::uninit(); bufsize]; |
| 2019 | let mut anc_buf: Vec<MaybeUninit<u8>> = vec![MaybeUninit::uninit(); ancbufsize]; |
| 2020 | let mut addr_storage: libc::sockaddr_storage = unsafe { core::mem::zeroed() }; |
| 2021 | |
| 2022 | // Set up iovec |
| 2023 | let mut iov = [libc::iovec { |
| 2024 | iov_base: data_buf.as_mut_ptr().cast(), |
| 2025 | iov_len: bufsize, |
| 2026 | }]; |
| 2027 | |
| 2028 | // Set up msghdr |
| 2029 | let mut msg: libc::msghdr = unsafe { core::mem::zeroed() }; |
| 2030 | msg.msg_name = (&mut addr_storage as *mut libc::sockaddr_storage).cast(); |
| 2031 | msg.msg_namelen = core::mem::size_of::<libc::sockaddr_storage>() as libc::socklen_t; |
| 2032 | msg.msg_iov = iov.as_mut_ptr(); |
| 2033 | msg.msg_iovlen = 1; |
| 2034 | if ancbufsize > 0 { |
| 2035 | msg.msg_control = anc_buf.as_mut_ptr().cast(); |
| 2036 | msg.msg_controllen = ancbufsize as _; |
| 2037 | } |
| 2038 | |
| 2039 | let n = self |
| 2040 | .sock_op(vm, SelectKind::Read, || { |
| 2041 | let sock = self.sock()?; |
| 2042 | let fd = sock_fileno(&sock); |
| 2043 | let ret = unsafe { libc::recvmsg(fd as libc::c_int, &mut msg, flags) }; |
| 2044 | if ret < 0 { |
| 2045 | Err(io::Error::last_os_error()) |
| 2046 | } else { |
| 2047 | Ok(ret as usize) |
| 2048 | } |
| 2049 | }) |
| 2050 | .map_err(|e| e.into_pyexception(vm))?; |
| 2051 | |
| 2052 | // Build data bytes |
| 2053 | let data = unsafe { |
nothing calls this directly
no test coverage detected