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

Fix the definition of sigevent on FreeBSD and Linux #3630

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
17 changes: 13 additions & 4 deletions libc-test/build.rs
Expand Up @@ -1955,6 +1955,9 @@ fn test_android(target: &str) {
("Elf32_Phdr", "p_type") => true,
("Elf64_Phdr", "p_type") => true,

// _sigev_un is an anonymous union
("sigevent", "_sigev_un") => true,

// this is actually a union on linux, so we can't represent it well and
// just insert some padding.
("siginfo_t", "_pad") => true,
Expand Down Expand Up @@ -2543,6 +2546,9 @@ fn test_freebsd(target: &str) {
// not available until FreeBSD 12, and is an anonymous union there.
("xucred", "cr_pid__c_anonymous_union") => true,

// Anonymous union
("sigevent", "_sigev_un") => true,

// m_owner field is a volatile __lwpid_t
("umutex", "m_owner") => true,
// c_has_waiters field is a volatile int32_t
Expand Down Expand Up @@ -2746,6 +2752,9 @@ fn test_emscripten(target: &str) {
});

cfg.skip_struct(move |ty| {
if ty.starts_with("__c_anonymous_") {
return true;
}
match ty {
// This is actually a union, not a struct
// FIXME: is this necessary?
Expand Down Expand Up @@ -2838,6 +2847,8 @@ fn test_emscripten(target: &str) {
});

cfg.skip_field(move |struct_, field| {
// _sigev_un is an anonymous union
(struct_ == "sigevent" && field == "_sigev_un") ||
// this is actually a union on linux, so we can't represent it well and
// just insert some padding.
// FIXME: is this necessary?
Expand All @@ -2848,8 +2859,6 @@ fn test_emscripten(target: &str) {
// musl seems to define this as an *anonymous* bitfield
// FIXME: is this necessary?
(struct_ == "statvfs" && field == "__f_unused") ||
// sigev_notify_thread_id is actually part of a sigev_un union
(struct_ == "sigevent" && field == "sigev_notify_thread_id") ||
// signalfd had SIGSYS fields added in Linux 4.18, but no libc release has them yet.
(struct_ == "signalfd_siginfo" && (field == "ssi_addr_lsb" ||
field == "_pad2" ||
Expand Down Expand Up @@ -4281,8 +4290,8 @@ fn test_linux(target: &str) {
(musl && struct_ == "glob_t" && field == "gl_flags") ||
// musl seems to define this as an *anonymous* bitfield
(musl && struct_ == "statvfs" && field == "__f_unused") ||
// sigev_notify_thread_id is actually part of a sigev_un union
(struct_ == "sigevent" && field == "sigev_notify_thread_id") ||
// _sigev_un is an anonymous union
(struct_ == "sigevent" && field == "_sigev_un") ||
// signalfd had SIGSYS fields added in Linux 4.18, but no libc release
// has them yet.
(struct_ == "signalfd_siginfo" && (field == "ssi_addr_lsb" ||
Expand Down
72 changes: 32 additions & 40 deletions src/unix/bsd/freebsdlike/freebsd/mod.rs
Expand Up @@ -237,20 +237,9 @@ impl ::Clone for devstat_select_mode {
}

s! {
pub struct aiocb {
pub aio_fildes: ::c_int,
pub aio_offset: ::off_t,
pub aio_buf: *mut ::c_void,
pub aio_nbytes: ::size_t,
__unused1: [::c_int; 2],
__unused2: *mut ::c_void,
pub aio_lio_opcode: ::c_int,
pub aio_reqprio: ::c_int,
// unused 3 through 5 are the __aiocb_private structure
__unused3: ::c_long,
__unused4: ::c_long,
__unused5: *mut ::c_void,
pub aio_sigevent: sigevent
pub struct __c_anonymous_sigev_thread {
pub _function: *mut ::c_void, // Actually a function pointer
pub _attribute: *mut ::pthread_attr_t,
}

pub struct jail {
Expand Down Expand Up @@ -1353,6 +1342,32 @@ s! {
}

s_no_extra_traits! {
#[cfg_attr(feature = "extra_traits", derive(Debug))]
pub struct aiocb {
pub aio_fildes: ::c_int,
pub aio_offset: ::off_t,
pub aio_buf: *mut ::c_void,
pub aio_nbytes: ::size_t,
__unused1: [::c_int; 2],
__unused2: *mut ::c_void,
pub aio_lio_opcode: ::c_int,
pub aio_reqprio: ::c_int,
// unused 3 through 5 are the __aiocb_private structure
__unused3: ::c_long,
__unused4: ::c_long,
__unused5: *mut ::c_void,
pub aio_sigevent: sigevent
}

// Can't correctly impl Debug for unions
#[allow(missing_debug_implementations)]
pub union __c_anonymous_sigev_un {
pub _threadid: ::__lwpid_t,
pub _sigev_thread: __c_anonymous_sigev_thread,
pub _kevent_flags: ::c_ushort,
__spare__: [::c_long; 8],
}

pub struct utmpx {
pub ut_type: ::c_short,
pub ut_tv: ::timeval,
Expand Down Expand Up @@ -1400,12 +1415,7 @@ s_no_extra_traits! {
pub sigev_notify: ::c_int,
pub sigev_signo: ::c_int,
pub sigev_value: ::sigval,
//The rest of the structure is actually a union. We expose only
//sigev_notify_thread_id because it's the most useful union member.
pub sigev_notify_thread_id: ::lwpid_t,
#[cfg(target_pointer_width = "64")]
__unused1: ::c_int,
__unused2: [::c_long; 7]
pub _sigev_un: __c_anonymous_sigev_un,
}

pub struct ptsstat {
Expand Down Expand Up @@ -1799,35 +1809,17 @@ cfg_if! {
}
}

impl PartialEq for sigevent {
fn eq(&self, other: &sigevent) -> bool {
self.sigev_notify == other.sigev_notify
&& self.sigev_signo == other.sigev_signo
&& self.sigev_value == other.sigev_value
&& self.sigev_notify_thread_id
== other.sigev_notify_thread_id
}
}
impl Eq for sigevent {}
impl ::fmt::Debug for sigevent {
fn fmt(&self, f: &mut ::fmt::Formatter) -> ::fmt::Result {
f.debug_struct("sigevent")
.field("sigev_notify", &self.sigev_notify)
.field("sigev_signo", &self.sigev_signo)
.field("sigev_value", &self.sigev_value)
.field("sigev_notify_thread_id",
&self.sigev_notify_thread_id)
// Skip _sigev_un, since we can't guarantee that it will be
// properly initialized.
.finish()
}
}
impl ::hash::Hash for sigevent {
fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
self.sigev_notify.hash(state);
self.sigev_signo.hash(state);
self.sigev_value.hash(state);
self.sigev_notify_thread_id.hash(state);
}
}

impl PartialEq for ptsstat {
fn eq(&self, other: &ptsstat) -> bool {
Expand Down
35 changes: 18 additions & 17 deletions src/unix/linux_like/emscripten/mod.rs
Expand Up @@ -171,23 +171,6 @@ s! {
pub sem_flg: ::c_short,
}

pub struct aiocb {
pub aio_fildes: ::c_int,
pub aio_lio_opcode: ::c_int,
pub aio_reqprio: ::c_int,
pub aio_buf: *mut ::c_void,
pub aio_nbytes: ::size_t,
pub aio_sigevent: ::sigevent,
__td: *mut ::c_void,
__lock: [::c_int; 2],
__err: ::c_int,
__ret: ::ssize_t,
pub aio_offset: off_t,
__next: *mut ::c_void,
__prev: *mut ::c_void,
__dummy4: [::c_char; 24],
}

pub struct sigaction {
pub sa_sigaction: ::sighandler_t,
pub sa_mask: ::sigset_t,
Expand Down Expand Up @@ -351,6 +334,24 @@ s! {
}

s_no_extra_traits! {
#[cfg_attr(feature = "extra_traits", derive(Debug))]
pub struct aiocb {
pub aio_fildes: ::c_int,
pub aio_lio_opcode: ::c_int,
pub aio_reqprio: ::c_int,
pub aio_buf: *mut ::c_void,
pub aio_nbytes: ::size_t,
pub aio_sigevent: ::sigevent,
__td: *mut ::c_void,
__lock: [::c_int; 2],
__err: ::c_int,
__ret: ::ssize_t,
pub aio_offset: off_t,
__next: *mut ::c_void,
__prev: *mut ::c_void,
__dummy4: [::c_char; 24],
}

pub struct dirent {
pub d_ino: ::ino_t,
pub d_off: ::off_t,
Expand Down
39 changes: 21 additions & 18 deletions src/unix/linux_like/linux/gnu/mod.rs
Expand Up @@ -49,24 +49,6 @@ s! {
pub __statx_timestamp_pad1: [i32; 1],
}

pub struct aiocb {
pub aio_fildes: ::c_int,
pub aio_lio_opcode: ::c_int,
pub aio_reqprio: ::c_int,
pub aio_buf: *mut ::c_void,
pub aio_nbytes: ::size_t,
pub aio_sigevent: ::sigevent,
__next_prio: *mut aiocb,
__abs_prio: ::c_int,
__policy: ::c_int,
__error_code: ::c_int,
__return_value: ::ssize_t,
pub aio_offset: off_t,
#[cfg(all(not(target_arch = "x86_64"), target_pointer_width = "32"))]
__unused1: [::c_char; 4],
__glibc_reserved: [::c_char; 32]
}

pub struct __exit_status {
pub e_termination: ::c_short,
pub e_exit: ::c_short,
Expand Down Expand Up @@ -481,6 +463,27 @@ impl siginfo_t {
}
}

s_no_extra_traits! {
#[cfg_attr(feature = "extra_traits", derive(Debug))]
pub struct aiocb {
pub aio_fildes: ::c_int,
pub aio_lio_opcode: ::c_int,
pub aio_reqprio: ::c_int,
pub aio_buf: *mut ::c_void,
pub aio_nbytes: ::size_t,
pub aio_sigevent: ::sigevent,
__next_prio: *mut aiocb,
__abs_prio: ::c_int,
__policy: ::c_int,
__error_code: ::c_int,
__return_value: ::ssize_t,
pub aio_offset: off_t,
#[cfg(all(not(target_arch = "x86_64"), target_pointer_width = "32"))]
__unused1: [::c_char; 4],
__glibc_reserved: [::c_char; 32]
}
}

// Internal, for casts to access union fields
#[repr(C)]
struct sifields_sigchld {
Expand Down
41 changes: 21 additions & 20 deletions src/unix/linux_like/linux/musl/mod.rs
Expand Up @@ -117,26 +117,6 @@ impl siginfo_t {
}

s! {
pub struct aiocb {
pub aio_fildes: ::c_int,
pub aio_lio_opcode: ::c_int,
pub aio_reqprio: ::c_int,
pub aio_buf: *mut ::c_void,
pub aio_nbytes: ::size_t,
pub aio_sigevent: ::sigevent,
__td: *mut ::c_void,
__lock: [::c_int; 2],
__err: ::c_int,
__ret: ::ssize_t,
pub aio_offset: off_t,
__next: *mut ::c_void,
__prev: *mut ::c_void,
#[cfg(target_pointer_width = "32")]
__dummy4: [::c_char; 24],
#[cfg(target_pointer_width = "64")]
__dummy4: [::c_char; 16],
}

pub struct sigaction {
pub sa_sigaction: ::sighandler_t,
pub sa_mask: ::sigset_t,
Expand Down Expand Up @@ -347,6 +327,27 @@ s! {
}

s_no_extra_traits! {
#[cfg_attr(feature = "extra_traits", derive(Debug))]
pub struct aiocb {
pub aio_fildes: ::c_int,
pub aio_lio_opcode: ::c_int,
pub aio_reqprio: ::c_int,
pub aio_buf: *mut ::c_void,
pub aio_nbytes: ::size_t,
pub aio_sigevent: ::sigevent,
__td: *mut ::c_void,
__lock: [::c_int; 2],
__err: ::c_int,
__ret: ::ssize_t,
pub aio_offset: off_t,
__next: *mut ::c_void,
__prev: *mut ::c_void,
#[cfg(target_pointer_width = "32")]
__dummy4: [::c_char; 24],
#[cfg(target_pointer_width = "64")]
__dummy4: [::c_char; 16],
}

pub struct sysinfo {
pub uptime: ::c_ulong,
pub loads: [::c_ulong; 3],
Expand Down