@@ -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
4040cfg_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