Add AncillaryError
This commit is contained in:
parent
6fa7c3f79e
commit
6f82ddf18e
4 changed files with 44 additions and 29 deletions
|
@ -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);
|
||||||
/// }
|
/// }
|
||||||
|
|
|
@ -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);
|
||||||
/// }
|
/// }
|
||||||
|
|
|
@ -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);
|
||||||
/// }
|
/// }
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue