diff --git a/libc-test/build.rs b/libc-test/build.rs index a3de6f94c2098..56f682be2f3f8 100644 --- a/libc-test/build.rs +++ b/libc-test/build.rs @@ -349,6 +349,13 @@ fn test_apple(target: &str) { } }); + cfg.skip_union(move |u| { + match u.ident() { + "sighandler_t" => true, + _ => false, + } + }); + cfg.skip_const(move |constant| { match constant.ident() { // They're declared via `deprecated_mach` and we don't support it anymore. @@ -368,6 +375,8 @@ fn test_apple(target: &str) { // FIXME(macos): bumped up on macOS 26, it's sizeof `vm_statistics64_data_t` "HOST_VM_INFO64_COUNT" => true, + "SIG_DFL" | "SIG_IGN" | "SIG_ERR" => true, + _ => false, } }); @@ -426,9 +435,6 @@ fn test_apple(target: &str) { .then_some(ty.to_string()) }); - // OSX calls this something else - cfg.rename_type(|ty| (ty == "sighandler_t").then_some("sig_t".to_string())); - cfg.rename_struct_ty(|ty| ty.ends_with("_t").then_some(ty.to_string())); cfg.rename_union_ty(|ty| ty.ends_with("_t").then_some(ty.to_string())); diff --git a/src/unix/bsd/apple/mod.rs b/src/unix/bsd/apple/mod.rs index d42f0ab16fd1f..715638c08bc2f 100644 --- a/src/unix/bsd/apple/mod.rs +++ b/src/unix/bsd/apple/mod.rs @@ -347,8 +347,8 @@ s! { _pad: Padding<[usize; 9]>, } + #[allow(unpredictable_function_pointer_comparisons)] pub struct sigaction { - // FIXME(union): this field is actually a union pub sa_sigaction: crate::sighandler_t, pub sa_mask: sigset_t, pub sa_flags: c_int, diff --git a/src/unix/linux_like/linux/musl/mod.rs b/src/unix/linux_like/linux/musl/mod.rs index 9d3009cba8809..ce8e5d55103b1 100644 --- a/src/unix/linux_like/linux/musl/mod.rs +++ b/src/unix/linux_like/linux/musl/mod.rs @@ -129,6 +129,13 @@ impl siginfo_t { } } +s_no_extra_traits! { + pub union sa_union_t { + pub sa_handler: crate::sighandler_t, + pub sa_sigaction: extern "C" fn(c_int, *mut crate::siginfo_t, *mut c_void), + } +} + s! { pub struct aiocb { pub aio_fildes: c_int, @@ -161,7 +168,7 @@ s! { // FIXME(1.0): This should not implement `PartialEq` #[allow(unpredictable_function_pointer_comparisons)] pub struct sigaction { - pub sa_sigaction: crate::sighandler_t, + pub sa_sigaction: sa_union_t, pub sa_mask: crate::sigset_t, pub sa_flags: c_int, pub sa_restorer: Option, diff --git a/src/unix/mod.rs b/src/unix/mod.rs index 207c36b82d55f..c071925cf0008 100644 --- a/src/unix/mod.rs +++ b/src/unix/mod.rs @@ -17,9 +17,19 @@ pub type ssize_t = isize; pub type pid_t = i32; pub type in_addr_t = u32; pub type in_port_t = u16; -pub type sighandler_t = size_t; pub type cc_t = c_uchar; +// All derivatives use sighandler_t to mean something which is either a +// function pointer or a size_t. And this has implications for its size +// (especially on CHERI architectures) compared to just blindly using size_t to +// represent it. +s_no_extra_traits! { + pub union sighandler_t { + pub sighandler_id: size_t, + pub sighandler_fn: extern "C" fn(c_int), + } +} + cfg_if! { if #[cfg(any( target_os = "espidf", @@ -229,9 +239,9 @@ s! { pub const INT_MIN: c_int = -2147483648; pub const INT_MAX: c_int = 2147483647; -pub const SIG_DFL: sighandler_t = 0 as sighandler_t; -pub const SIG_IGN: sighandler_t = 1 as sighandler_t; -pub const SIG_ERR: sighandler_t = !0 as sighandler_t; +pub const SIG_DFL: size_t = 0 as size_t; +pub const SIG_IGN: size_t = 1 as size_t; +pub const SIG_ERR: size_t = !0 as size_t; cfg_if! { if #[cfg(all(