Use unsafe blocks in signal.h implementation
This commit is contained in:
committed by
sourceturner
parent
a426887528
commit
b3add24654
+71
-60
@@ -2,6 +2,9 @@
|
||||
//!
|
||||
//! See <https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/signal.h.html>.
|
||||
|
||||
// TODO: set this for entire crate when possible
|
||||
#![deny(unsafe_op_in_unsafe_fn)]
|
||||
|
||||
use core::{arch::global_asm, mem, ptr};
|
||||
|
||||
use cbitset::BitSet;
|
||||
@@ -141,16 +144,16 @@ unsafe extern "C" {
|
||||
unsafe extern "C" fn __sigsetjmp_tail(jb: *mut u64, ret: i32) -> i32 {
|
||||
let set = jb.wrapping_add(9);
|
||||
if ret > 0 {
|
||||
sigprocmask(SIG_SETMASK, set, ptr::null_mut());
|
||||
unsafe { sigprocmask(SIG_SETMASK, set, ptr::null_mut()) };
|
||||
} else {
|
||||
sigprocmask(SIG_SETMASK, ptr::null_mut(), set);
|
||||
unsafe { sigprocmask(SIG_SETMASK, ptr::null_mut(), set) };
|
||||
}
|
||||
ret
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn siglongjmp(jb: *mut u64, ret: i32) {
|
||||
setjmp::longjmp(jb, ret);
|
||||
unsafe { setjmp::longjmp(jb, ret) };
|
||||
}
|
||||
|
||||
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/kill.html>.
|
||||
@@ -177,10 +180,10 @@ pub extern "C" fn killpg(pgrp: pid_t, sig: c_int) -> c_int {
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn pthread_kill(thread: pthread_t, sig: c_int) -> c_int {
|
||||
let os_tid = {
|
||||
let pthread = &*(thread as *const crate::pthread::Pthread);
|
||||
pthread.os_tid.get().read()
|
||||
let pthread = unsafe { &*(thread as *const crate::pthread::Pthread) };
|
||||
unsafe { pthread.os_tid.get().read() }
|
||||
};
|
||||
crate::header::pthread::e(Sys::rlct_kill(os_tid, sig as usize))
|
||||
crate::header::pthread::e(unsafe { Sys::rlct_kill(os_tid, sig as usize) })
|
||||
}
|
||||
|
||||
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/pthread_sigmask.html>.
|
||||
@@ -191,7 +194,7 @@ pub unsafe extern "C" fn pthread_sigmask(
|
||||
oldset: *mut sigset_t,
|
||||
) -> c_int {
|
||||
// On Linux and Redox, pthread_sigmask and sigprocmask are equivalent
|
||||
if sigprocmask(how, set, oldset) == 0 {
|
||||
if unsafe { sigprocmask(how, set, oldset) } == 0 {
|
||||
0
|
||||
} else {
|
||||
//TODO: Fix race
|
||||
@@ -212,7 +215,7 @@ pub unsafe extern "C" fn sigaction(
|
||||
act: *const sigaction,
|
||||
oact: *mut sigaction,
|
||||
) -> c_int {
|
||||
Sys::sigaction(sig, act.as_ref(), oact.as_mut())
|
||||
Sys::sigaction(sig, unsafe { act.as_ref() }, unsafe { oact.as_mut() })
|
||||
.map(|()| 0)
|
||||
.or_minus_one_errno()
|
||||
}
|
||||
@@ -236,9 +239,11 @@ pub unsafe extern "C" fn sigaddset(set: *mut sigset_t, signo: c_int) -> c_int {
|
||||
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/sigaltstack.html>.
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn sigaltstack(ss: *const stack_t, old_ss: *mut stack_t) -> c_int {
|
||||
Sys::sigaltstack(ss.as_ref(), old_ss.as_mut())
|
||||
.map(|()| 0)
|
||||
.or_minus_one_errno()
|
||||
unsafe {
|
||||
Sys::sigaltstack(ss.as_ref(), old_ss.as_mut())
|
||||
.map(|()| 0)
|
||||
.or_minus_one_errno()
|
||||
}
|
||||
}
|
||||
|
||||
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/sigdelset.html>.
|
||||
@@ -260,7 +265,7 @@ pub unsafe extern "C" fn sigdelset(set: *mut sigset_t, signo: c_int) -> c_int {
|
||||
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/sigemptyset.html>.
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn sigemptyset(set: *mut sigset_t) -> c_int {
|
||||
if let Some(set) = (set as *mut SigSet).as_mut() {
|
||||
if let Some(set) = unsafe { (set as *mut SigSet).as_mut() } {
|
||||
set.clear();
|
||||
}
|
||||
0
|
||||
@@ -269,7 +274,7 @@ pub unsafe extern "C" fn sigemptyset(set: *mut sigset_t) -> c_int {
|
||||
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/sigfillset.html>.
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn sigfillset(set: *mut sigset_t) -> c_int {
|
||||
if let Some(set) = (set as *mut SigSet).as_mut() {
|
||||
if let Some(set) = unsafe { (set as *mut SigSet).as_mut() } {
|
||||
set.fill(.., true);
|
||||
}
|
||||
0
|
||||
@@ -285,10 +290,10 @@ pub unsafe extern "C" fn sighold(sig: c_int) -> c_int {
|
||||
let mut pset = mem::MaybeUninit::<sigset_t>::uninit();
|
||||
unsafe { sigemptyset(pset.as_mut_ptr()) };
|
||||
let mut set = unsafe { pset.assume_init() };
|
||||
if sigaddset(&mut set, sig) < 0 {
|
||||
if unsafe { sigaddset(&mut set, sig) } < 0 {
|
||||
return -1;
|
||||
}
|
||||
sigprocmask(SIG_BLOCK, &set, ptr::null_mut())
|
||||
unsafe { sigprocmask(SIG_BLOCK, &set, ptr::null_mut()) }
|
||||
}
|
||||
|
||||
/// See <https://pubs.opengroup.org/onlinepubs/9699919799/functions/sighold.html>.
|
||||
@@ -367,18 +372,18 @@ pub extern "C" fn signal(
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn sigpause(sig: c_int) -> c_int {
|
||||
let mut pset = mem::MaybeUninit::<sigset_t>::uninit();
|
||||
sigprocmask(0, ptr::null_mut(), pset.as_mut_ptr());
|
||||
let mut set = pset.assume_init();
|
||||
if sigdelset(&mut set, sig) == -1 {
|
||||
unsafe { sigprocmask(0, ptr::null_mut(), pset.as_mut_ptr()) };
|
||||
let mut set = unsafe { pset.assume_init() };
|
||||
if unsafe { sigdelset(&mut set, sig) } == -1 {
|
||||
return -1;
|
||||
}
|
||||
sigsuspend(&set)
|
||||
unsafe { sigsuspend(&set) }
|
||||
}
|
||||
|
||||
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/sigpending.html>.
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn sigpending(set: *mut sigset_t) -> c_int {
|
||||
(|| Sys::sigpending(set.as_mut().ok_or(Errno(EFAULT))?))()
|
||||
(|| Sys::sigpending(unsafe { set.as_mut().ok_or(Errno(EFAULT)) }?))()
|
||||
.map(|()| 0)
|
||||
.or_minus_one_errno()
|
||||
}
|
||||
@@ -395,8 +400,8 @@ pub unsafe extern "C" fn sigprocmask(
|
||||
oset: *mut sigset_t,
|
||||
) -> c_int {
|
||||
(|| {
|
||||
let set = set.as_ref().map(|&block| block & !RLCT_SIGNAL_MASK);
|
||||
let mut oset = oset.as_mut();
|
||||
let set = unsafe { set.as_ref().map(|&block| block & !RLCT_SIGNAL_MASK) };
|
||||
let mut oset = unsafe { oset.as_mut() };
|
||||
|
||||
Sys::sigprocmask(
|
||||
how,
|
||||
@@ -421,12 +426,12 @@ pub unsafe extern "C" fn sigprocmask(
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn sigrelse(sig: c_int) -> c_int {
|
||||
let mut pset = mem::MaybeUninit::<sigset_t>::uninit();
|
||||
sigemptyset(pset.as_mut_ptr());
|
||||
let mut set = pset.assume_init();
|
||||
if sigaddset(&mut set, sig) < 0 {
|
||||
unsafe { sigemptyset(pset.as_mut_ptr()) };
|
||||
let mut set = unsafe { pset.assume_init() };
|
||||
if unsafe { sigaddset(&mut set, sig) } < 0 {
|
||||
return -1;
|
||||
}
|
||||
sigprocmask(SIG_UNBLOCK, &mut set, ptr::null_mut())
|
||||
unsafe { sigprocmask(SIG_UNBLOCK, &mut set, ptr::null_mut()) }
|
||||
}
|
||||
|
||||
/// See <https://pubs.opengroup.org/onlinepubs/9699919799/functions/sighold.html>.
|
||||
@@ -441,16 +446,16 @@ pub unsafe extern "C" fn sigset(
|
||||
) -> Option<extern "C" fn(c_int)> {
|
||||
let mut old_sa = mem::MaybeUninit::uninit();
|
||||
let mut pset = mem::MaybeUninit::<sigset_t>::uninit();
|
||||
let sig_hold: Option<extern "C" fn(c_int)> = mem::transmute(SIG_HOLD);
|
||||
let sig_err: Option<extern "C" fn(c_int)> = mem::transmute(SIG_ERR);
|
||||
sigemptyset(pset.as_mut_ptr());
|
||||
let mut set = pset.assume_init();
|
||||
if sigaddset(&mut set, sig) < 0 {
|
||||
let sig_hold: Option<extern "C" fn(c_int)> = unsafe { mem::transmute(SIG_HOLD) };
|
||||
let sig_err: Option<extern "C" fn(c_int)> = unsafe { mem::transmute(SIG_ERR) };
|
||||
unsafe { sigemptyset(pset.as_mut_ptr()) };
|
||||
let mut set = unsafe { pset.assume_init() };
|
||||
if unsafe { sigaddset(&mut set, sig) } < 0 {
|
||||
return sig_err;
|
||||
} else {
|
||||
if func == sig_hold {
|
||||
if sigaction(sig, ptr::null_mut(), old_sa.as_mut_ptr()) < 0
|
||||
|| sigprocmask(SIG_BLOCK, &mut set, &mut set) < 0
|
||||
if unsafe { sigaction(sig, ptr::null_mut(), old_sa.as_mut_ptr()) } < 0
|
||||
|| unsafe { sigprocmask(SIG_BLOCK, &mut set, &mut set) } < 0
|
||||
{
|
||||
mem::forget(old_sa);
|
||||
return sig_err;
|
||||
@@ -462,36 +467,36 @@ pub unsafe extern "C" fn sigset(
|
||||
sa_restorer: None, // set by platform if applicable
|
||||
sa_mask: sigset_t::default(),
|
||||
};
|
||||
sigemptyset(&mut sa.sa_mask);
|
||||
if sigaction(sig, &sa, old_sa.as_mut_ptr()) < 0
|
||||
|| sigprocmask(SIG_UNBLOCK, &mut set, &mut set) < 0
|
||||
unsafe { sigemptyset(&mut sa.sa_mask) };
|
||||
if unsafe { sigaction(sig, &sa, old_sa.as_mut_ptr()) } < 0
|
||||
|| unsafe { sigprocmask(SIG_UNBLOCK, &mut set, &mut set) } < 0
|
||||
{
|
||||
mem::forget(old_sa);
|
||||
return sig_err;
|
||||
}
|
||||
}
|
||||
}
|
||||
if sigismember(&mut set, sig) == 1 {
|
||||
if unsafe { sigismember(&mut set, sig) } == 1 {
|
||||
return sig_hold;
|
||||
}
|
||||
old_sa.assume_init().sa_handler
|
||||
unsafe { old_sa.assume_init().sa_handler }
|
||||
}
|
||||
|
||||
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/sigsuspend.html>.
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn sigsuspend(sigmask: *const sigset_t) -> c_int {
|
||||
Err(Sys::sigsuspend(&*sigmask)).or_minus_one_errno()
|
||||
Err(Sys::sigsuspend(unsafe { &*sigmask })).or_minus_one_errno()
|
||||
}
|
||||
|
||||
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/sigwait.html>.
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn sigwait(set: *const sigset_t, sig: *mut c_int) -> c_int {
|
||||
let mut pinfo = mem::MaybeUninit::<siginfo_t>::uninit();
|
||||
if sigtimedwait(set, pinfo.as_mut_ptr(), ptr::null_mut()) < 0 {
|
||||
if unsafe { sigtimedwait(set, pinfo.as_mut_ptr(), ptr::null_mut()) } < 0 {
|
||||
return -1;
|
||||
}
|
||||
let info = pinfo.assume_init();
|
||||
(*sig) = info.si_signo;
|
||||
let info = unsafe { pinfo.assume_init() };
|
||||
unsafe { (*sig) = info.si_signo };
|
||||
0
|
||||
}
|
||||
|
||||
@@ -505,15 +510,17 @@ pub unsafe extern "C" fn sigtimedwait(
|
||||
// to differentiate between sigtimedwait and sigwaitinfo internally
|
||||
tp: *const timespec,
|
||||
) -> c_int {
|
||||
Sys::sigtimedwait(&*set, sig.as_mut(), tp.as_ref())
|
||||
.map(|()| 0)
|
||||
.or_minus_one_errno()
|
||||
Sys::sigtimedwait(unsafe { &*set }, unsafe { sig.as_mut() }, unsafe {
|
||||
tp.as_ref()
|
||||
})
|
||||
.map(|()| 0)
|
||||
.or_minus_one_errno()
|
||||
}
|
||||
|
||||
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/sigwaitinfo.html>.
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn sigwaitinfo(set: *const sigset_t, sig: *mut siginfo_t) -> c_int {
|
||||
sigtimedwait(set, sig, core::ptr::null())
|
||||
unsafe { sigtimedwait(set, sig, core::ptr::null()) }
|
||||
}
|
||||
|
||||
pub(crate) const SIGNAL_STRINGS: [&str; 32] = [
|
||||
@@ -559,15 +566,17 @@ pub unsafe extern "C" fn psignal(sig: c_int, prefix: *const c_char) {
|
||||
.and_then(|idx| SIGNAL_STRINGS.get(idx))
|
||||
.unwrap_or(&SIGNAL_STRINGS[0]);
|
||||
let description = &c_description[..c_description.len() - 1];
|
||||
let prefix = CStr::from_ptr(prefix).to_string_lossy();
|
||||
let prefix = unsafe { CStr::from_ptr(prefix).to_string_lossy() };
|
||||
// TODO: stack vec or print directly?
|
||||
let string = alloc::format!("{prefix}:{description}\n");
|
||||
// TODO: better internal libc API?
|
||||
let _ = unistd::write(
|
||||
unistd::STDERR_FILENO,
|
||||
string.as_bytes().as_ptr().cast(),
|
||||
string.as_bytes().len(),
|
||||
);
|
||||
let _ = unsafe {
|
||||
unistd::write(
|
||||
unistd::STDERR_FILENO,
|
||||
string.as_bytes().as_ptr().cast(),
|
||||
string.as_bytes().len(),
|
||||
)
|
||||
};
|
||||
}
|
||||
|
||||
/// See <https://pubs.opengroup.org/onlinepubs/9799919799/functions/psiginfo.html>.
|
||||
@@ -582,9 +591,9 @@ pub unsafe extern "C" fn psiginfo(info: *const siginfo_t, prefix: *const c_char)
|
||||
si_addr,
|
||||
si_status,
|
||||
si_value,
|
||||
} = &*info;
|
||||
let sival_ptr = si_value.sival_ptr;
|
||||
let prefix = CStr::from_ptr(prefix).to_string_lossy();
|
||||
} = unsafe { &*info };
|
||||
let sival_ptr = unsafe { si_value.sival_ptr };
|
||||
let prefix = unsafe { CStr::from_ptr(prefix).to_string_lossy() };
|
||||
// TODO: stack vec or print directly?
|
||||
let string = alloc::format!(
|
||||
"{prefix}:siginfo_t {{
|
||||
@@ -600,11 +609,13 @@ pub unsafe extern "C" fn psiginfo(info: *const siginfo_t, prefix: *const c_char)
|
||||
"
|
||||
);
|
||||
// TODO: better internal libc API?
|
||||
let _ = unistd::write(
|
||||
unistd::STDERR_FILENO,
|
||||
string.as_bytes().as_ptr().cast(),
|
||||
string.as_bytes().len(),
|
||||
);
|
||||
let _ = unsafe {
|
||||
unistd::write(
|
||||
unistd::STDERR_FILENO,
|
||||
string.as_bytes().as_ptr().cast(),
|
||||
string.as_bytes().len(),
|
||||
)
|
||||
};
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
|
||||
Reference in New Issue
Block a user