Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rollup of 7 pull requests #83664

Merged
merged 20 commits into from
Mar 30, 2021
Merged
Changes from 1 commit
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
6233f3f
alloc: Added `as_slice` method to `BinaryHeap` collection
frol Feb 20, 2021
dd2b8a0
provide a more realistic example for BinaryHeap::as_slice
frol Mar 13, 2021
3d6bd87
unix: Fix feature(unix_socket_ancillary_data) on macos and other BSDs
reyk Mar 22, 2021
4572e7f
Lint on unknown intra-doc link disambiguators
camelid Mar 27, 2021
c20ba9c
Add escape_default method to u8 and [u8]
clarfonthey Oct 24, 2020
56347a1
Point to disambiguator instead of whole link
camelid Mar 29, 2021
5497f15
Add test for weird backticks placement
camelid Mar 29, 2021
141df6f
Inline `find_suffix` closure that's only used once
camelid Mar 29, 2021
29d4a7d
Add a regression test for issue-82792
JohnTitor Mar 29, 2021
c9562fd
Prefer 4 spaces
JohnTitor Mar 29, 2021
48f9f08
Remove a FIXME resolved by #73578
JohnTitor Mar 29, 2021
79acd5e
:arrow_up: rust-analyzer
lnicola Mar 29, 2021
595f3f2
Updated the tracking issue #
frol Mar 29, 2021
2843baa
Rollup merge of #82331 - frol:feat/std-binary-heap-as-slice, r=Amanieu
Dylan-DPC Mar 29, 2021
68964d1
Rollup merge of #83130 - clarfonthey:escape, r=m-ou-se
Dylan-DPC Mar 29, 2021
772582e
Rollup merge of #83374 - reyk:fix/bsd-ancillary, r=joshtriplett
Dylan-DPC Mar 29, 2021
25ade69
Rollup merge of #83543 - camelid:lint-unknown-disambiguator, r=jyn514
Dylan-DPC Mar 29, 2021
6b5ba53
Rollup merge of #83636 - JohnTitor:const-generics-defualts-regg-test,…
Dylan-DPC Mar 29, 2021
fca8e7d
Rollup merge of #83643 - JohnTitor:is-freeze-no-longer-uses-span, r=R…
Dylan-DPC Mar 29, 2021
6738ee7
Rollup merge of #83644 - lnicola:rust-analyzer-2021-03-29, r=jonas-sc…
Dylan-DPC Mar 29, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
unix: Fix feature(unix_socket_ancillary_data) on macos and other BSDs
This adds support for CMSG handling on macOS and fixes it on OpenBSD
and other BSDs.

When traversing the CMSG list, the previous code had an exception for
Android where the next element after the last pointer could point to
the first pointer instead of NULL.  This is actually not specific to
Android: the `libc::CMSG_NXTHDR` implementation for Linux and
emscripten have a special case to return NULL when the length of the
previous element is zero; most other implementations simply return the
previous element plus a zero offset in this case.

This MR additionally adds `SocketAncillary::is_empty` because clippy
is right that it should be added.
reyk committed Mar 26, 2021
commit 3d6bd87b24a2fbccb6c1e81863874789eb046c17
57 changes: 34 additions & 23 deletions library/std/src/sys/unix/ext/net/ancillary.rs
Original file line number Diff line number Diff line change
@@ -5,9 +5,7 @@ use crate::marker::PhantomData;
use crate::mem::{size_of, zeroed};
use crate::os::unix::io::RawFd;
use crate::path::Path;
#[cfg(target_os = "android")]
use crate::ptr::eq;
use crate::ptr::read_unaligned;
use crate::ptr::{eq, read_unaligned};
use crate::slice::from_raw_parts;
use crate::sys::net::Socket;

@@ -30,12 +28,10 @@ pub(super) fn recv_vectored_with_ancillary_from(
) -> io::Result<(usize, bool, io::Result<SocketAddr>)> {
unsafe {
let mut msg_name: libc::sockaddr_un = zeroed();

let mut msg: libc::msghdr = zeroed();
msg.msg_name = &mut msg_name as *mut _ as *mut _;
msg.msg_namelen = size_of::<libc::sockaddr_un>() as libc::socklen_t;
msg.msg_iov = bufs.as_mut_ptr().cast();
msg.msg_control = ancillary.buffer.as_mut_ptr().cast();
cfg_if::cfg_if! {
if #[cfg(any(target_os = "android", all(target_os = "linux", target_env = "gnu")))] {
msg.msg_iovlen = bufs.len() as libc::size_t;
@@ -45,13 +41,18 @@ pub(super) fn recv_vectored_with_ancillary_from(
target_os = "emscripten",
target_os = "freebsd",
all(target_os = "linux", target_env = "musl",),
target_os = "macos",
target_os = "netbsd",
target_os = "openbsd",
))] {
msg.msg_iovlen = bufs.len() as libc::c_int;
msg.msg_controllen = ancillary.buffer.len() as libc::socklen_t;
}
}
// macos requires that the control pointer is NULL when the len is 0.
if msg.msg_controllen > 0 {
msg.msg_control = ancillary.buffer.as_mut_ptr().cast();
}

let count = socket.recv_msg(&mut msg)?;

@@ -79,7 +80,6 @@ pub(super) fn send_vectored_with_ancillary_to(
msg.msg_name = &mut msg_name as *mut _ as *mut _;
msg.msg_namelen = msg_namelen;
msg.msg_iov = bufs.as_ptr() as *mut _;
msg.msg_control = ancillary.buffer.as_mut_ptr().cast();
cfg_if::cfg_if! {
if #[cfg(any(target_os = "android", all(target_os = "linux", target_env = "gnu")))] {
msg.msg_iovlen = bufs.len() as libc::size_t;
@@ -89,13 +89,18 @@ pub(super) fn send_vectored_with_ancillary_to(
target_os = "emscripten",
target_os = "freebsd",
all(target_os = "linux", target_env = "musl",),
target_os = "macos",
target_os = "netbsd",
target_os = "openbsd",
))] {
msg.msg_iovlen = bufs.len() as libc::c_int;
msg.msg_controllen = ancillary.length as libc::socklen_t;
}
}
// macos requires that the control pointer is NULL when the len is 0.
if msg.msg_controllen > 0 {
msg.msg_control = ancillary.buffer.as_mut_ptr().cast();
}

ancillary.truncated = false;

@@ -147,6 +152,7 @@ fn add_to_ancillary_data<T>(
target_os = "emscripten",
target_os = "freebsd",
all(target_os = "linux", target_env = "musl",),
target_os = "macos",
target_os = "netbsd",
target_os = "openbsd",
))] {
@@ -159,14 +165,12 @@ fn add_to_ancillary_data<T>(
while !cmsg.is_null() {
previous_cmsg = cmsg;
cmsg = libc::CMSG_NXTHDR(&msg, cmsg);
cfg_if::cfg_if! {
// Android return the same pointer if it is the last cmsg.
// Therefore, check it if the previous pointer is the same as the current one.
if #[cfg(target_os = "android")] {
if cmsg == previous_cmsg {
break;
}
}

// Most operating systems, but not Linux or emscripten, return the previous pointer
// when its length is zero. Therefore, check if the previous pointer is the same as
// the current one.
if eq(cmsg, previous_cmsg) {
break;
}
}

@@ -184,6 +188,7 @@ fn add_to_ancillary_data<T>(
target_os = "emscripten",
target_os = "freebsd",
all(target_os = "linux", target_env = "musl",),
target_os = "macos",
target_os = "netbsd",
target_os = "openbsd",
))] {
@@ -371,6 +376,7 @@ impl<'a> AncillaryData<'a> {
target_os = "emscripten",
target_os = "freebsd",
all(target_os = "linux", target_env = "musl",),
target_os = "macos",
target_os = "netbsd",
target_os = "openbsd",
))] {
@@ -421,6 +427,7 @@ impl<'a> Iterator for Messages<'a> {
target_os = "emscripten",
target_os = "freebsd",
all(target_os = "linux", target_env = "musl",),
target_os = "macos",
target_os = "netbsd",
target_os = "openbsd",
))] {
@@ -435,15 +442,13 @@ impl<'a> Iterator for Messages<'a> {
};

let cmsg = cmsg.as_ref()?;
cfg_if::cfg_if! {
// Android return the same pointer if it is the last cmsg.
// Therefore, check it if the previous pointer is the same as the current one.
if #[cfg(target_os = "android")] {
if let Some(current) = self.current {
if eq(current, cmsg) {
return None;
}
}

// Most operating systems, but not Linux or emscripten, return the previous pointer
// when its length is zero. Therefore, check if the previous pointer is the same as
// the current one.
if let Some(current) = self.current {
if eq(current, cmsg) {
return None;
}
}

@@ -514,6 +519,12 @@ impl<'a> SocketAncillary<'a> {
self.buffer.len()
}

/// Returns `true` if the ancillary data is empty.
#[unstable(feature = "unix_socket_ancillary_data", issue = "76915")]
pub fn is_empty(&self) -> bool {
self.length == 0
}

/// Returns the number of used bytes.
#[unstable(feature = "unix_socket_ancillary_data", issue = "76915")]
pub fn len(&self) -> usize {