()
| 751 | #[cfg(not(target_os = "freebsd"))] // TODO: Investigate why these tests fail on FreeBSD. |
| 752 | #[test] |
| 753 | fn test_unix_msg_with_combo() { |
| 754 | crate::init(); |
| 755 | |
| 756 | use rustix::fd::AsFd as _; |
| 757 | use rustix::io::{IoSlice, IoSliceMut}; |
| 758 | use rustix::net::{ |
| 759 | recvmsg, sendmsg, RecvAncillaryBuffer, RecvAncillaryMessage, RecvFlags, ReturnFlags, |
| 760 | SendAncillaryBuffer, SendAncillaryMessage, SendFlags, |
| 761 | }; |
| 762 | use rustix::pipe::pipe; |
| 763 | use std::string::ToString as _; |
| 764 | |
| 765 | let tmpdir = tempfile::tempdir().unwrap(); |
| 766 | let path = tmpdir.path().join("scp_4804"); |
| 767 | |
| 768 | let server = { |
| 769 | let path = path.clone(); |
| 770 | |
| 771 | let connection_socket = socket(AddressFamily::UNIX, SocketType::SEQPACKET, None).unwrap(); |
| 772 | |
| 773 | let name = SocketAddrUnix::new(&path).unwrap(); |
| 774 | bind(&connection_socket, &name).unwrap(); |
| 775 | listen(&connection_socket, 1).unwrap(); |
| 776 | |
| 777 | move || { |
| 778 | let mut pipe_end = None; |
| 779 | let mut another_pipe_end = None; |
| 780 | let mut yet_another_pipe_end = None; |
| 781 | |
| 782 | let mut buffer = [0; BUFFER_SIZE]; |
| 783 | let mut cmsg_space = |
| 784 | [MaybeUninit::uninit(); rustix::cmsg_space!(ScmRights(2), ScmRights(1))]; |
| 785 | |
| 786 | 'exit: loop { |
| 787 | let data_socket = accept(&connection_socket).unwrap(); |
| 788 | let mut sum = 0; |
| 789 | loop { |
| 790 | let mut cmsg_buffer = RecvAncillaryBuffer::new(cmsg_space.as_mut_slice()); |
| 791 | let result = recvmsg( |
| 792 | &data_socket, |
| 793 | &mut [IoSliceMut::new(&mut buffer)], |
| 794 | &mut cmsg_buffer, |
| 795 | RecvFlags::empty(), |
| 796 | ) |
| 797 | .unwrap(); |
| 798 | let nread = result.bytes; |
| 799 | |
| 800 | assert_eq!(result.flags, ReturnFlags::empty()); |
| 801 | |
| 802 | // Read out the pipe if we got it. |
| 803 | for cmsg in cmsg_buffer.drain() { |
| 804 | match cmsg { |
| 805 | RecvAncillaryMessage::ScmRights(rights) => { |
| 806 | for right in rights { |
| 807 | if pipe_end.is_none() { |
| 808 | pipe_end = Some(right); |
| 809 | } else if another_pipe_end.is_none() { |
| 810 | another_pipe_end = Some(right); |
nothing calls this directly
no test coverage detected