Merge branch 'master' of https://gitlab.redox-os.org/redox-os/relibc
This commit is contained in:
@@ -14,7 +14,7 @@ pub type sa_family_t = u16;
|
||||
pub type socklen_t = u32;
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Default)]
|
||||
#[derive(Default, CheckVsLibcCrate)]
|
||||
pub struct linger {
|
||||
pub l_onoff: c_int,
|
||||
pub l_linger: c_int,
|
||||
@@ -24,7 +24,7 @@ pub struct linger {
|
||||
pub extern "C" fn _cbindgen_export_linger(linger: linger) {}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, CheckVsLibcCrate)]
|
||||
pub struct msghdr {
|
||||
pub msg_name: *mut c_void,
|
||||
pub msg_namelen: socklen_t,
|
||||
@@ -36,7 +36,7 @@ pub struct msghdr {
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, CheckVsLibcCrate)]
|
||||
pub struct cmsghdr {
|
||||
pub cmsg_len: size_t,
|
||||
pub cmsg_level: c_int,
|
||||
@@ -45,6 +45,7 @@ pub struct cmsghdr {
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
// FIXME: CheckVsLibcCrate
|
||||
pub struct ucred {
|
||||
pub pid: pid_t,
|
||||
pub uid: uid_t,
|
||||
@@ -55,7 +56,7 @@ pub struct ucred {
|
||||
pub extern "C" fn _cbindgen_export_cmsghdr(cmsghdr: cmsghdr) {}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Default)]
|
||||
#[derive(Default, CheckVsLibcCrate)]
|
||||
pub struct sockaddr {
|
||||
pub sa_family: sa_family_t,
|
||||
pub sa_data: [c_char; 14],
|
||||
@@ -75,6 +76,7 @@ const _SS_PADDING: usize = _SS_MAXSIZE - mem::size_of::<sa_family_t>() - mem::si
|
||||
/// * The order of the fields is important because the bytes in the padding will be cast to and
|
||||
/// from protocol structs in C
|
||||
#[repr(C)]
|
||||
//#[derive(CheckVsLibcCrate)] FIXME: can't ignore private fields yet
|
||||
pub struct sockaddr_storage {
|
||||
pub ss_family: sa_family_t,
|
||||
__ss_pad2: [u8; _SS_PADDING],
|
||||
|
||||
@@ -55,7 +55,7 @@ impl LogSink for LogFile {
|
||||
connect(
|
||||
log_fd,
|
||||
&raw const log_addr as *const sockaddr,
|
||||
size_of::<sockaddr_un>(),
|
||||
size_of::<sockaddr_un>() as u32,
|
||||
) < 0
|
||||
} {
|
||||
// In case close sets ERRNO.
|
||||
|
||||
@@ -11,7 +11,7 @@ use crate::{
|
||||
pub const IOV_MAX: c_int = 1024;
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, CheckVsLibcCrate)]
|
||||
pub struct iovec {
|
||||
pub iov_base: *mut c_void,
|
||||
pub iov_len: size_t,
|
||||
|
||||
@@ -410,3 +410,86 @@ macro_rules! OutProject {
|
||||
unsafe impl $crate::out::OutProject for $name {}
|
||||
}
|
||||
}
|
||||
#[macro_export]
|
||||
#[cfg(not(feature = "check_against_libc_crate"))]
|
||||
macro_rules! CheckVsLibcCrate {
|
||||
derive() { $(#[$($attrs:meta),*])* $v:vis struct $name:ident {
|
||||
$(
|
||||
$(#[$($fa:meta),*])* $fv:vis $field:ident : $type:ty
|
||||
),*$(,)?
|
||||
} } => {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: probably exists nice nightly features that allow conflicting impls. Then we wouldn't need
|
||||
// much of this redundant code just to say A == B -> B == A and say A == B -> *mut A == *mut B.
|
||||
pub trait LibcTypeEquals<A, B> {}
|
||||
//impl<A, B> LibcTypeEquals<A, B> for () {}
|
||||
impl<A, B> LibcTypeEquals<*mut A, *mut B> for () where (): LibcTypeEquals<A, B> {}
|
||||
impl<A, B> LibcTypeEquals<*const A, *const B> for () where (): LibcTypeEquals<A, B> {}
|
||||
impl<A, B, const N: usize> LibcTypeEquals<[A; N], [B; N]> for () where (): LibcTypeEquals<A, B> {}
|
||||
macro_rules! for_primitive_int(
|
||||
($i:ident) => {
|
||||
impl LibcTypeEquals<$i, $i> for () {}
|
||||
}
|
||||
);
|
||||
for_primitive_int!(u8);
|
||||
for_primitive_int!(u16);
|
||||
for_primitive_int!(u32);
|
||||
for_primitive_int!(u64);
|
||||
for_primitive_int!(u128);
|
||||
for_primitive_int!(usize);
|
||||
for_primitive_int!(i8);
|
||||
for_primitive_int!(i16);
|
||||
for_primitive_int!(i32);
|
||||
for_primitive_int!(i64);
|
||||
for_primitive_int!(i128);
|
||||
for_primitive_int!(isize);
|
||||
impl LibcTypeEquals<crate::platform::types::c_void, crate::platform::types::c_void> for () {}
|
||||
impl LibcTypeEquals<__libc_only_for_layout_checks::c_void, crate::platform::types::c_void> for () {}
|
||||
impl LibcTypeEquals<crate::platform::types::c_void, __libc_only_for_layout_checks::c_void> for () {}
|
||||
|
||||
//impl LibcTypeEquals<__libc_only_for_layout_checks::c_void>
|
||||
|
||||
/// Derive macro which checks that structs here are defined the same as in the libc crate. Perhaps
|
||||
/// not sufficiently rigorous to soundly cast between the types, but should catch most mistakes.
|
||||
#[macro_export]
|
||||
#[cfg(feature = "check_against_libc_crate")]
|
||||
macro_rules! CheckVsLibcCrate {
|
||||
// XXX: not sure we can have the name be different from libc::$name without parameters to the
|
||||
// derive macro
|
||||
derive() { $(#[$($attrs:meta),*])* $v:vis struct $name:ident {
|
||||
$(
|
||||
$(#[$($fa:meta),*])* $fv:vis $field:ident : $type:ty
|
||||
),*$(,)?
|
||||
} } => {
|
||||
// TODO: check repr(C)? probably possible to match on $attrs
|
||||
#[allow(dead_code)]
|
||||
const _: () = {
|
||||
if ::core::mem::size_of::<$name>() != ::core::mem::size_of::<::__libc_only_for_layout_checks::$name>() {
|
||||
panic!("struct size mismatch");
|
||||
}
|
||||
if ::core::mem::align_of::<$name>() != ::core::mem::align_of::<::__libc_only_for_layout_checks::$name>() {
|
||||
panic!("struct alignment mismatch");
|
||||
}
|
||||
$(
|
||||
if ::core::mem::offset_of!($name, $field) != ::core::mem::offset_of!(__libc_only_for_layout_checks::$name, $field) {
|
||||
panic!("struct field offset mismatch");
|
||||
}
|
||||
)*
|
||||
};
|
||||
$(
|
||||
// check all field types are equivalent
|
||||
#[allow(dead_code)]
|
||||
const _: () = {
|
||||
fn ensure_ty<A, B>(a: A, b: B) where (): $crate::macros::LibcTypeEquals::<A, B> {}
|
||||
fn for_libc(a: $name, b: __libc_only_for_layout_checks::$name) {
|
||||
let a: $type = panic!("never called");
|
||||
ensure_ty(a, b.$field);
|
||||
}
|
||||
};
|
||||
)*
|
||||
impl $crate::macros::LibcTypeEquals<$name, __libc_only_for_layout_checks::$name> for () {}
|
||||
impl $crate::macros::LibcTypeEquals<__libc_only_for_layout_checks::$name, $name> for () {}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -716,8 +716,7 @@ impl PalSocket for Sys {
|
||||
}
|
||||
_ => {
|
||||
let metadata = [SocketCall::GetSockOpt as u64, option_name as u64];
|
||||
let payload =
|
||||
slice::from_raw_parts_mut(option_value as *mut u8, option_len);
|
||||
let payload = slice::from_raw_parts_mut(option_value as *mut u8, option_len);
|
||||
let call_flags = CallFlags::empty();
|
||||
*option_len_ptr = redox_rt::sys::sys_call(
|
||||
socket as usize,
|
||||
@@ -810,7 +809,7 @@ impl PalSocket for Sys {
|
||||
+ mem::size_of::<usize>() // payload_len
|
||||
+ whole_iov_size // payload_data_buffer
|
||||
+ mem::size_of::<usize>() // control_len
|
||||
+ mhdr.msg_controllen as usize // ancillary_stream_buffer
|
||||
+ mhdr.msg_controllen as usize // ancillary_stream_buffer
|
||||
};
|
||||
msg_stream
|
||||
.try_reserve_exact(expected_stream_size)
|
||||
|
||||
Reference in New Issue
Block a user