Skip to content

Commit 7c44d46

Browse files
authored
Rollup merge of rust-lang#100782 - thomcc:fix-android-sigaddset, r=Mark-Simulacrum
Align android `sigaddset` impl with the reference impl from Bionic In rust-lang#100737 I noticed we were treating the sigset_t as an array of bytes, while referencing code from android (https://github.com/aosp-mirror/platform_bionic/blob/ad8dcd6023294b646e5a8288c0ed431b0845da49/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.
2 parents e8182e8 + f506656 commit 7c44d46

File tree

1 file changed

+23
-3
lines changed

1 file changed

+23
-3
lines changed

library/std/src/sys/unix/process/process_common.rs

+23-3
Original file line numberDiff line numberDiff line change
@@ -45,11 +45,31 @@ cfg_if::cfg_if! {
4545
}
4646
#[allow(dead_code)]
4747
pub unsafe fn sigaddset(set: *mut libc::sigset_t, signum: libc::c_int) -> libc::c_int {
48-
use crate::{slice, mem};
48+
use crate::{
49+
mem::{align_of, size_of},
50+
slice,
51+
};
52+
use libc::{c_ulong, sigset_t};
53+
54+
// The implementations from bionic (android libc) type pun `sigset_t` as an
55+
// array of `c_ulong`. This works, but lets add a smoke check to make sure
56+
// that doesn't change.
57+
const _: () = assert!(
58+
align_of::<c_ulong>() == align_of::<sigset_t>()
59+
&& (size_of::<sigset_t>() % size_of::<c_ulong>()) == 0
60+
);
4961

50-
let raw = slice::from_raw_parts_mut(set as *mut u8, mem::size_of::<libc::sigset_t>());
5162
let bit = (signum - 1) as usize;
52-
raw[bit / 8] |= 1 << (bit % 8);
63+
if set.is_null() || bit < 0 || bit >= (8 * size_of::<sigset_t>()) {
64+
crate::sys::unix::os::set_errno(libc::EINVAL);
65+
return -1;
66+
}
67+
let raw = slice::from_raw_parts_mut(
68+
set as *mut c_ulong,
69+
size_of::<sigset_t>() / size_of::<c_ulong>(),
70+
);
71+
const LONG_BIT: usize = size_of::<c_ulong>() * 8;
72+
raw[bit / LONG_BIT] |= 1 << (bit % LONG_BIT);
5373
return 0;
5474
}
5575
} else {

0 commit comments

Comments
 (0)