1
Fork 0

Add AncillaryError

This commit is contained in:
LinkTed 2020-08-22 20:25:43 +02:00
parent 6fa7c3f79e
commit 6f82ddf18e
4 changed files with 44 additions and 29 deletions

View file

@ -1,3 +1,4 @@
use crate::convert::TryFrom;
use crate::io::{self, IoSliceMut}; use crate::io::{self, IoSliceMut};
use crate::mem; use crate::mem;
use crate::os::unix::io::RawFd; use crate::os::unix::io::RawFd;
@ -145,6 +146,13 @@ impl<'a> Iterator for ScmCredentials<'a> {
} }
} }
#[non_exhaustive]
#[derive(Debug)]
#[unstable(feature = "unix_socket_ancillary_data", issue = "none")]
pub enum AncillaryError {
Unknown { cmsg_level: i32, cmsg_type: i32 },
}
#[cfg(any( #[cfg(any(
target_os = "haiku", target_os = "haiku",
target_os = "solaris", target_os = "solaris",
@ -240,17 +248,19 @@ impl<'a> AncillaryData<'a> {
target_env = "uclibc", target_env = "uclibc",
))] ))]
#[unstable(feature = "unix_socket_ancillary_data", issue = "none")] #[unstable(feature = "unix_socket_ancillary_data", issue = "none")]
impl<'a> AncillaryData<'a> { impl<'a> TryFrom<&'a libc::cmsghdr> for AncillaryData<'a> {
fn from(cmsg: &'a libc::cmsghdr) -> Self { type Error = AncillaryError;
fn try_from(cmsg: &'a libc::cmsghdr) -> Result<Self, Self::Error> {
unsafe { unsafe {
let cmsg_len_zero = libc::CMSG_LEN(0) as usize; let cmsg_len_zero = libc::CMSG_LEN(0) as usize;
let data_len = (*cmsg).cmsg_len - cmsg_len_zero; let data_len = (*cmsg).cmsg_len - cmsg_len_zero;
let data = libc::CMSG_DATA(cmsg).cast(); let data = libc::CMSG_DATA(cmsg).cast();
let data = from_raw_parts(data, data_len); let data = from_raw_parts(data, data_len);
if (*cmsg).cmsg_level == libc::SOL_SOCKET { match (*cmsg).cmsg_level {
match (*cmsg).cmsg_type { libc::SOL_SOCKET => match (*cmsg).cmsg_type {
libc::SCM_RIGHTS => AncillaryData::as_rights(data), libc::SCM_RIGHTS => Ok(AncillaryData::as_rights(data)),
#[cfg(any( #[cfg(any(
target_os = "linux", target_os = "linux",
target_os = "android", target_os = "android",
@ -258,7 +268,7 @@ impl<'a> AncillaryData<'a> {
target_os = "fuchsia", target_os = "fuchsia",
target_env = "uclibc", target_env = "uclibc",
))] ))]
libc::SCM_CREDENTIALS => AncillaryData::as_credentials(data), libc::SCM_CREDENTIALS => Ok(AncillaryData::as_credentials(data)),
#[cfg(any( #[cfg(any(
target_os = "netbsd", target_os = "netbsd",
target_os = "openbsd", target_os = "openbsd",
@ -267,11 +277,14 @@ impl<'a> AncillaryData<'a> {
target_os = "macos", target_os = "macos",
target_os = "ios", target_os = "ios",
))] ))]
libc::SCM_CREDS => AncillaryData::as_credentials(data), libc::SCM_CREDS => Ok(AncillaryData::as_credentials(data)),
_ => panic!("Unknown cmsg type"), cmsg_type => {
Err(AncillaryError::Unknown { cmsg_level: libc::SOL_SOCKET, cmsg_type })
}
},
cmsg_level => {
Err(AncillaryError::Unknown { cmsg_level, cmsg_type: (*cmsg).cmsg_type })
} }
} else {
panic!("Unknown cmsg level");
} }
} }
} }
@ -317,9 +330,9 @@ pub struct Messages<'a> {
))] ))]
#[unstable(feature = "unix_socket_ancillary_data", issue = "none")] #[unstable(feature = "unix_socket_ancillary_data", issue = "none")]
impl<'a> Iterator for Messages<'a> { impl<'a> Iterator for Messages<'a> {
type Item = AncillaryData<'a>; type Item = Result<AncillaryData<'a>, AncillaryError>;
fn next(&mut self) -> Option<AncillaryData<'a>> { fn next(&mut self) -> Option<Self::Item> {
unsafe { unsafe {
let msg = libc::msghdr { let msg = libc::msghdr {
msg_name: null_mut(), msg_name: null_mut(),
@ -339,8 +352,8 @@ impl<'a> Iterator for Messages<'a> {
let cmsg = cmsg.as_ref()?; let cmsg = cmsg.as_ref()?;
self.current = Some(cmsg); self.current = Some(cmsg);
let ancillary_data = AncillaryData::from(cmsg); let ancillary_result = AncillaryData::try_from(cmsg);
Some(ancillary_data) Some(ancillary_result)
} }
} }
} }
@ -364,8 +377,8 @@ impl<'a> Iterator for Messages<'a> {
/// let mut bufs = &mut [IoSliceMut::new(&mut buf[..])][..]; /// let mut bufs = &mut [IoSliceMut::new(&mut buf[..])][..];
/// sock.recv_vectored_with_ancillary(bufs, &mut ancillary)?; /// sock.recv_vectored_with_ancillary(bufs, &mut ancillary)?;
/// ///
/// for ancillary_data in ancillary.messages() { /// for ancillary_result in ancillary.messages() {
/// if let AncillaryData::ScmRights(scm_rights) = ancillary_data { /// if let AncillaryData::ScmRights(scm_rights) = ancillary_result.unwrap() {
/// for fd in scm_rights { /// for fd in scm_rights {
/// println!("receive file descriptor: {}", fd); /// println!("receive file descriptor: {}", fd);
/// } /// }
@ -585,8 +598,8 @@ impl<'a> SocketAncillary<'a> {
/// let mut bufs = &mut [IoSliceMut::new(&mut buf[..])][..]; /// let mut bufs = &mut [IoSliceMut::new(&mut buf[..])][..];
/// ///
/// sock.recv_vectored_with_ancillary(bufs, &mut ancillary)?; /// sock.recv_vectored_with_ancillary(bufs, &mut ancillary)?;
/// for ancillary_data in ancillary.messages() { /// for ancillary_result in ancillary.messages() {
/// if let AncillaryData::ScmRights(scm_rights) = ancillary_data { /// if let AncillaryData::ScmRights(scm_rights) = ancillary_result.unwrap() {
/// for fd in scm_rights { /// for fd in scm_rights {
/// println!("receive file descriptor: {}", fd); /// println!("receive file descriptor: {}", fd);
/// } /// }
@ -596,8 +609,8 @@ impl<'a> SocketAncillary<'a> {
/// ancillary.clear(); /// ancillary.clear();
/// ///
/// sock.recv_vectored_with_ancillary(bufs, &mut ancillary)?; /// sock.recv_vectored_with_ancillary(bufs, &mut ancillary)?;
/// for ancillary_data in ancillary.messages() { /// for ancillary_result in ancillary.messages() {
/// if let AncillaryData::ScmRights(scm_rights) = ancillary_data { /// if let AncillaryData::ScmRights(scm_rights) = ancillary_result.unwrap() {
/// for fd in scm_rights { /// for fd in scm_rights {
/// println!("receive file descriptor: {}", fd); /// println!("receive file descriptor: {}", fd);
/// } /// }

View file

@ -343,8 +343,8 @@ impl UnixDatagram {
/// let mut ancillary = SocketAncillary::new(&mut ancillary_buffer[..]); /// let mut ancillary = SocketAncillary::new(&mut ancillary_buffer[..]);
/// let (size, _truncated, sender) = sock.recv_vectored_with_ancillary_from(bufs, &mut ancillary)?; /// let (size, _truncated, sender) = sock.recv_vectored_with_ancillary_from(bufs, &mut ancillary)?;
/// println!("received {}", size); /// println!("received {}", size);
/// for ancillary_data in ancillary.messages() { /// for ancillary_result in ancillary.messages() {
/// if let AncillaryData::ScmRights(scm_rights) = ancillary_data { /// if let AncillaryData::ScmRights(scm_rights) = ancillary_result.unwrap() {
/// for fd in scm_rights { /// for fd in scm_rights {
/// println!("receive file descriptor: {}", fd); /// println!("receive file descriptor: {}", fd);
/// } /// }
@ -391,8 +391,8 @@ impl UnixDatagram {
/// let mut ancillary = SocketAncillary::new(&mut ancillary_buffer[..]); /// let mut ancillary = SocketAncillary::new(&mut ancillary_buffer[..]);
/// let (size, _truncated) = sock.recv_vectored_with_ancillary(bufs, &mut ancillary)?; /// let (size, _truncated) = sock.recv_vectored_with_ancillary(bufs, &mut ancillary)?;
/// println!("received {}", size); /// println!("received {}", size);
/// for ancillary_data in ancillary.messages() { /// for ancillary_result in ancillary.messages() {
/// if let AncillaryData::ScmRights(scm_rights) = ancillary_data { /// if let AncillaryData::ScmRights(scm_rights) = ancillary_result.unwrap() {
/// for fd in scm_rights { /// for fd in scm_rights {
/// println!("receive file descriptor: {}", fd); /// println!("receive file descriptor: {}", fd);
/// } /// }

View file

@ -451,8 +451,8 @@ impl UnixStream {
/// let mut ancillary = SocketAncillary::new(&mut ancillary_buffer[..]); /// let mut ancillary = SocketAncillary::new(&mut ancillary_buffer[..]);
/// let size = socket.recv_vectored_with_ancillary(bufs, &mut ancillary)?; /// let size = socket.recv_vectored_with_ancillary(bufs, &mut ancillary)?;
/// println!("received {}", size); /// println!("received {}", size);
/// for ancillary_data in ancillary.messages() { /// for ancillary_result in ancillary.messages() {
/// if let AncillaryData::ScmRights(scm_rights) = ancillary_data { /// if let AncillaryData::ScmRights(scm_rights) = ancillary_result.unwrap() {
/// for fd in scm_rights { /// for fd in scm_rights {
/// println!("receive file descriptor: {}", fd); /// println!("receive file descriptor: {}", fd);
/// } /// }

View file

@ -481,7 +481,7 @@ fn test_send_vectored_fds_unix_stream() {
let mut ancillary_data_vec = Vec::from_iter(ancillary2.messages()); let mut ancillary_data_vec = Vec::from_iter(ancillary2.messages());
assert_eq!(ancillary_data_vec.len(), 1); assert_eq!(ancillary_data_vec.len(), 1);
if let AncillaryData::ScmRights(scm_rights) = ancillary_data_vec.pop().unwrap() { if let AncillaryData::ScmRights(scm_rights) = ancillary_data_vec.pop().unwrap().unwrap() {
let fd_vec = Vec::from_iter(scm_rights); let fd_vec = Vec::from_iter(scm_rights);
assert_eq!(fd_vec.len(), 1); assert_eq!(fd_vec.len(), 1);
unsafe { unsafe {
@ -551,7 +551,9 @@ fn test_send_vectored_with_ancillary_to_unix_datagram() {
let mut ancillary_data_vec = Vec::from_iter(ancillary2.messages()); let mut ancillary_data_vec = Vec::from_iter(ancillary2.messages());
assert_eq!(ancillary_data_vec.len(), 1); assert_eq!(ancillary_data_vec.len(), 1);
if let AncillaryData::ScmCredentials(scm_credentials) = ancillary_data_vec.pop().unwrap() { if let AncillaryData::ScmCredentials(scm_credentials) =
ancillary_data_vec.pop().unwrap().unwrap()
{
let cred_vec = Vec::from_iter(scm_credentials); let cred_vec = Vec::from_iter(scm_credentials);
assert_eq!(cred_vec.len(), 1); assert_eq!(cred_vec.len(), 1);
assert_eq!(cred1.pid, cred_vec[0].pid); assert_eq!(cred1.pid, cred_vec[0].pid);
@ -596,7 +598,7 @@ fn test_send_vectored_with_ancillary_unix_datagram() {
let mut ancillary_data_vec = Vec::from_iter(ancillary2.messages()); let mut ancillary_data_vec = Vec::from_iter(ancillary2.messages());
assert_eq!(ancillary_data_vec.len(), 1); assert_eq!(ancillary_data_vec.len(), 1);
if let AncillaryData::ScmRights(scm_rights) = ancillary_data_vec.pop().unwrap() { if let AncillaryData::ScmRights(scm_rights) = ancillary_data_vec.pop().unwrap().unwrap() {
let fd_vec = Vec::from_iter(scm_rights); let fd_vec = Vec::from_iter(scm_rights);
assert_eq!(fd_vec.len(), 1); assert_eq!(fd_vec.len(), 1);
unsafe { unsafe {