Skip to content

Commit 7b9651f

Browse files
committed
Implement sigdelset and sigismember for Android
We're going to need this for upcoming signal mask support.
1 parent bb8a08f commit 7b9651f

File tree

1 file changed

+57
-9
lines changed

1 file changed

+57
-9
lines changed

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

+57-9
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,9 @@ cfg_if::cfg_if! {
3232
}
3333
}
3434

35-
// Android with api less than 21 define sig* functions inline, so it is not
36-
// available for dynamic link. Implementing sigemptyset and sigaddset allow us
37-
// to support older Android version (independent of libc version).
35+
// Android with api less than 21 define sig* functions inline, so they are not
36+
// available for dynamic linking. Implementing these functions allows us
37+
// to support older Android versions (independent of libc version).
3838
// The following implementations are based on
3939
// https://github.com/aosp-mirror/platform_bionic/blob/ad8dcd6023294b646e5a8288c0ed431b0845da49/libc/include/android/legacy_signal_inlines.h
4040
cfg_if::cfg_if! {
@@ -43,8 +43,58 @@ cfg_if::cfg_if! {
4343
set.write_bytes(0u8, 1);
4444
return 0;
4545
}
46+
47+
const LONG_BIT: usize = crate::mem::size_of::<libc::c_ulong>() * 8;
48+
4649
#[allow(dead_code)]
4750
pub unsafe fn sigaddset(set: *mut libc::sigset_t, signum: libc::c_int) -> libc::c_int {
51+
let bit = (signum - 1) as usize;
52+
let raw = match to_bitmap_slice_mut(set, bit) {
53+
Ok(raw) => raw,
54+
Err(val) => return val,
55+
};
56+
raw[bit / LONG_BIT] |= 1 << (bit % LONG_BIT);
57+
return 0;
58+
}
59+
60+
#[allow(dead_code)]
61+
pub unsafe fn sigdelset(set: *mut libc::sigset_t, signum: libc::c_int) -> libc::c_int {
62+
let bit = (signum - 1) as usize;
63+
let raw = match to_bitmap_slice_mut(set, bit) {
64+
Ok(raw) => raw,
65+
Err(val) => return val,
66+
};
67+
raw[bit / LONG_BIT] &= !(1 << (bit % LONG_BIT));
68+
return 0;
69+
}
70+
71+
#[allow(dead_code)]
72+
pub unsafe fn sigismember(set: *const libc::sigset_t, signum: libc::c_int) -> libc::c_int {
73+
// Can't use to_bitmap_slice_mut because it's *mut, not *const.
74+
use crate::{
75+
mem::size_of,
76+
slice,
77+
};
78+
use libc::{c_ulong, sigset_t};
79+
80+
let bit = (signum - 1) as usize;
81+
if set.is_null() || bit >= (8 * size_of::<sigset_t>()) {
82+
crate::sys::unix::os::set_errno(libc::EINVAL);
83+
return -1;
84+
}
85+
let raw: &[c_ulong] = slice::from_raw_parts(
86+
set as *const c_ulong,
87+
size_of::<sigset_t>() / size_of::<c_ulong>(),
88+
);
89+
90+
return ((raw[bit / LONG_BIT] >> (bit % LONG_BIT)) & 1) as i32;
91+
}
92+
93+
// SAFETY: returned slice lives as long as set.
94+
unsafe fn to_bitmap_slice_mut<'a>(
95+
set: *mut libc::sigset_t,
96+
bit: usize,
97+
) -> Result<&'a mut [libc::c_ulong], libc::c_int> {
4898
use crate::{
4999
mem::{align_of, size_of},
50100
slice,
@@ -59,21 +109,19 @@ cfg_if::cfg_if! {
59109
&& (size_of::<sigset_t>() % size_of::<c_ulong>()) == 0
60110
);
61111

62-
let bit = (signum - 1) as usize;
63112
if set.is_null() || bit >= (8 * size_of::<sigset_t>()) {
64113
crate::sys::unix::os::set_errno(libc::EINVAL);
65-
return -1;
114+
return Err(-1);
66115
}
67116
let raw = slice::from_raw_parts_mut(
68117
set as *mut c_ulong,
69118
size_of::<sigset_t>() / size_of::<c_ulong>(),
70119
);
71-
const LONG_BIT: usize = size_of::<c_ulong>() * 8;
72-
raw[bit / LONG_BIT] |= 1 << (bit % LONG_BIT);
73-
return 0;
120+
121+
Ok(raw)
74122
}
75123
} else {
76-
pub use libc::{sigemptyset, sigaddset};
124+
pub use libc::{sigemptyset, sigaddset, sigdelset, sigismember};
77125
}
78126
}
79127

0 commit comments

Comments
 (0)