mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-25 08:13:41 +00:00
Auto merge of #100782 - thomcc:fix-android-sigaddset, r=Mark-Simulacrum
Align android `sigaddset` impl with the reference impl from Bionic
In https://github.com/rust-lang/rust/pull/100737 I noticed we were treating the sigset_t as an array of bytes, while referencing code from android (ad8dcd6023/libc/include/android/legacy_signal_inlines.h
) which treats it as an array of unsigned long.
That said, the behavior difference is so subtle here that it's not hard to see why nobody noticed. This fixes the implementation to be equivalent to the one in bionic.
This commit is contained in:
commit
1cff564203
@ -45,11 +45,31 @@ cfg_if::cfg_if! {
|
||||
}
|
||||
#[allow(dead_code)]
|
||||
pub unsafe fn sigaddset(set: *mut libc::sigset_t, signum: libc::c_int) -> libc::c_int {
|
||||
use crate::{slice, mem};
|
||||
use crate::{
|
||||
mem::{align_of, size_of},
|
||||
slice,
|
||||
};
|
||||
use libc::{c_ulong, sigset_t};
|
||||
|
||||
// The implementations from bionic (android libc) type pun `sigset_t` as an
|
||||
// array of `c_ulong`. This works, but lets add a smoke check to make sure
|
||||
// that doesn't change.
|
||||
const _: () = assert!(
|
||||
align_of::<c_ulong>() == align_of::<sigset_t>()
|
||||
&& (size_of::<sigset_t>() % size_of::<c_ulong>()) == 0
|
||||
);
|
||||
|
||||
let raw = slice::from_raw_parts_mut(set as *mut u8, mem::size_of::<libc::sigset_t>());
|
||||
let bit = (signum - 1) as usize;
|
||||
raw[bit / 8] |= 1 << (bit % 8);
|
||||
if set.is_null() || bit >= (8 * size_of::<sigset_t>()) {
|
||||
crate::sys::unix::os::set_errno(libc::EINVAL);
|
||||
return -1;
|
||||
}
|
||||
let raw = slice::from_raw_parts_mut(
|
||||
set as *mut c_ulong,
|
||||
size_of::<sigset_t>() / size_of::<c_ulong>(),
|
||||
);
|
||||
const LONG_BIT: usize = size_of::<c_ulong>() * 8;
|
||||
raw[bit / LONG_BIT] |= 1 << (bit % LONG_BIT);
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
|
Loading…
Reference in New Issue
Block a user