(hdr: &cmsghdr)
| 13 | } |
| 14 | impl CMsg { |
| 15 | pub fn parse(hdr: &cmsghdr) -> AxResult<Self> { |
| 16 | if hdr.cmsg_len < size_of::<cmsghdr>() { |
| 17 | return Err(AxError::InvalidInput); |
| 18 | } |
| 19 | |
| 20 | let data = |
| 21 | UserConstPtr::<u8>::from((hdr as *const cmsghdr as usize) + size_of::<cmsghdr>()) |
| 22 | .get_as_slice(hdr.cmsg_len - size_of::<cmsghdr>())?; |
| 23 | Ok(match (hdr.cmsg_level as u32, hdr.cmsg_type as u32) { |
| 24 | (SOL_SOCKET, SCM_RIGHTS) => { |
| 25 | if data.len() % size_of::<i32>() != 0 { |
| 26 | return Err(AxError::InvalidInput); |
| 27 | } |
| 28 | let mut fds = Vec::new(); |
| 29 | for fd in data.chunks_exact(size_of::<i32>()) { |
| 30 | let fd = i32::from_ne_bytes(fd.try_into().unwrap()); |
| 31 | if fd < 0 { |
| 32 | return Err(AxError::BadFileDescriptor); |
| 33 | } |
| 34 | let f = get_file_like(fd)?; |
| 35 | fds.push(f); |
| 36 | } |
| 37 | Self::Rights { fds } |
| 38 | } |
| 39 | _ => { |
| 40 | return Err(AxError::InvalidInput); |
| 41 | } |
| 42 | }) |
| 43 | } |
| 44 | } |
| 45 | |
| 46 | pub struct CMsgBuilder<'a> { |
nothing calls this directly
no test coverage detected