(
fd: i32,
mut dst: impl Write + IoBufMut,
flags: u32,
addr: UserPtr<sockaddr>,
addrlen: UserPtr<socklen_t>,
cmsg_builder: Option<CMsgBuilder>,
)
| 82 | } |
| 83 | |
| 84 | fn recv_impl( |
| 85 | fd: i32, |
| 86 | mut dst: impl Write + IoBufMut, |
| 87 | flags: u32, |
| 88 | addr: UserPtr<sockaddr>, |
| 89 | addrlen: UserPtr<socklen_t>, |
| 90 | cmsg_builder: Option<CMsgBuilder>, |
| 91 | ) -> AxResult<isize> { |
| 92 | debug!("sys_recv <= fd: {fd}, flags: {flags}"); |
| 93 | |
| 94 | let socket = Socket::from_fd(fd)?; |
| 95 | let mut recv_flags = RecvFlags::empty(); |
| 96 | if flags & MSG_PEEK != 0 { |
| 97 | recv_flags |= RecvFlags::PEEK; |
| 98 | } |
| 99 | if flags & MSG_TRUNC != 0 { |
| 100 | recv_flags |= RecvFlags::TRUNCATE; |
| 101 | } |
| 102 | |
| 103 | let mut cmsg = Vec::new(); |
| 104 | |
| 105 | let mut remote_addr = |
| 106 | (!addr.is_null()).then(|| SocketAddrEx::Ip((Ipv4Addr::UNSPECIFIED, 0).into())); |
| 107 | let recv = socket.recv( |
| 108 | &mut dst, |
| 109 | RecvOptions { |
| 110 | from: remote_addr.as_mut(), |
| 111 | flags: recv_flags, |
| 112 | cmsg: Some(&mut cmsg), |
| 113 | }, |
| 114 | )?; |
| 115 | |
| 116 | if let Some(remote_addr) = remote_addr { |
| 117 | remote_addr.write_to_user(addr, addrlen.get_as_mut()?)?; |
| 118 | } |
| 119 | |
| 120 | if let Some(mut builder) = cmsg_builder { |
| 121 | for cmsg in cmsg { |
| 122 | let Ok(cmsg) = cmsg.downcast::<CMsg>() else { |
| 123 | warn!("received unexpected cmsg"); |
| 124 | continue; |
| 125 | }; |
| 126 | |
| 127 | let pushed = match *cmsg { |
| 128 | CMsg::Rights { fds } => builder.push(SOL_SOCKET, SCM_RIGHTS, |data| { |
| 129 | let mut written = 0; |
| 130 | for (f, chunk) in fds.into_iter().zip(data.chunks_exact_mut(size_of::<i32>())) { |
| 131 | let fd = add_file_like(f, false)?; |
| 132 | chunk.copy_from_slice(&fd.to_ne_bytes()); |
| 133 | written += size_of::<i32>(); |
| 134 | } |
| 135 | Ok(written) |
| 136 | })?, |
| 137 | }; |
| 138 | if !pushed { |
| 139 | break; |
| 140 | } |
| 141 | } |
no test coverage detected