mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-08 18:26:48 +00:00
feat:添加sigprocmask系统调用 (#1046)
* 添加sigprocmask系统调用 --------- Signed-off-by: sparkzky <sparkhhhhhhhhh@outlook.com> Co-authored-by: longjin <longjin@DragonOS.org>
This commit is contained in:
parent
4f8f269baf
commit
6e85059fbc
@ -12,7 +12,7 @@ use crate::{
|
|||||||
},
|
},
|
||||||
exception::InterruptArch,
|
exception::InterruptArch,
|
||||||
ipc::{
|
ipc::{
|
||||||
signal::set_current_sig_blocked,
|
signal::set_current_blocked,
|
||||||
signal_types::{SaHandlerType, SigInfo, Sigaction, SigactionType, SignalArch},
|
signal_types::{SaHandlerType, SigInfo, Sigaction, SigactionType, SignalArch},
|
||||||
},
|
},
|
||||||
mm::MemoryManagementArch,
|
mm::MemoryManagementArch,
|
||||||
@ -511,7 +511,7 @@ impl SignalArch for X86_64SignalArch {
|
|||||||
return trap_frame.rax;
|
return trap_frame.rax;
|
||||||
}
|
}
|
||||||
let mut sigmask: SigSet = unsafe { (*frame).context.oldmask };
|
let mut sigmask: SigSet = unsafe { (*frame).context.oldmask };
|
||||||
set_current_sig_blocked(&mut sigmask);
|
set_current_blocked(&mut sigmask);
|
||||||
// 从用户栈恢复sigcontext
|
// 从用户栈恢复sigcontext
|
||||||
if !unsafe { &mut (*frame).context }.restore_sigcontext(trap_frame) {
|
if !unsafe { &mut (*frame).context }.restore_sigcontext(trap_frame) {
|
||||||
error!("unable to restore sigcontext");
|
error!("unable to restore sigcontext");
|
||||||
|
@ -441,18 +441,46 @@ pub(super) fn do_sigaction(
|
|||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 设置当前进程的屏蔽信号 (sig_block),待引入 [sigprocmask](https://man7.org/linux/man-pages/man2/sigprocmask.2.html) 系统调用后要删除这个散装函数
|
/// https://code.dragonos.org.cn/xref/linux-6.6.21/include/uapi/asm-generic/signal-defs.h#72
|
||||||
///
|
/// 对应SIG_BLOCK,SIG_UNBLOCK,SIG_SETMASK
|
||||||
/// ## 参数
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
///
|
pub enum SigHow {
|
||||||
/// - `new_set` 新的屏蔽信号bitmap的值
|
Block = 0,
|
||||||
pub fn set_current_sig_blocked(new_set: &mut SigSet) {
|
Unblock = 1,
|
||||||
let to_remove: SigSet =
|
SetMask = 2,
|
||||||
<Signal as Into<SigSet>>::into(Signal::SIGKILL) | Signal::SIGSTOP.into();
|
}
|
||||||
new_set.remove(to_remove);
|
|
||||||
//TODO 把这个散装函数用 sigsetops 替换掉
|
|
||||||
let pcb = ProcessManager::current_pcb();
|
|
||||||
|
|
||||||
|
impl TryFrom<i32> for SigHow {
|
||||||
|
type Error = SystemError;
|
||||||
|
fn try_from(value: i32) -> Result<Self, Self::Error> {
|
||||||
|
match value {
|
||||||
|
0 => Ok(SigHow::Block),
|
||||||
|
1 => Ok(SigHow::Unblock),
|
||||||
|
2 => Ok(SigHow::SetMask),
|
||||||
|
_ => Err(SystemError::EINVAL),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn __set_task_blocked(pcb: &Arc<ProcessControlBlock>, new_set: &SigSet) {
|
||||||
|
//todo 还有一个对线程组是否为空的判断,进程组、线程组实现之后,需要更改这里。
|
||||||
|
if pcb.has_pending_signal() {
|
||||||
|
let mut newblocked = *new_set;
|
||||||
|
let guard = pcb.sig_info_irqsave();
|
||||||
|
newblocked.remove(*guard.sig_block());
|
||||||
|
drop(guard);
|
||||||
|
|
||||||
|
// 从主线程开始去遍历
|
||||||
|
if let Some(group_leader) = pcb.threads_read_irqsave().group_leader() {
|
||||||
|
retarget_shared_pending(group_leader, newblocked);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*pcb.sig_info_mut().sig_block_mut() = *new_set;
|
||||||
|
recalc_sigpending();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn __set_current_blocked(new_set: &SigSet) {
|
||||||
|
let pcb = ProcessManager::current_pcb();
|
||||||
/*
|
/*
|
||||||
如果当前pcb的sig_blocked和新的相等,那么就不用改变它。
|
如果当前pcb的sig_blocked和新的相等,那么就不用改变它。
|
||||||
请注意,一个进程的sig_blocked字段不能被其他进程修改!
|
请注意,一个进程的sig_blocked字段不能被其他进程修改!
|
||||||
@ -460,12 +488,97 @@ pub fn set_current_sig_blocked(new_set: &mut SigSet) {
|
|||||||
if pcb.sig_info_irqsave().sig_block().eq(new_set) {
|
if pcb.sig_info_irqsave().sig_block().eq(new_set) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let guard = pcb.sig_struct_irqsave();
|
let guard = pcb.sig_struct_irqsave();
|
||||||
// todo: 当一个进程有多个线程后,在这里需要设置每个线程的block字段,并且 retarget_shared_pending(虽然我还没搞明白linux这部分是干啥的)
|
|
||||||
|
|
||||||
// 设置当前进程的sig blocked
|
__set_task_blocked(&pcb, new_set);
|
||||||
*pcb.sig_info_mut().sig_block_mut() = *new_set;
|
|
||||||
recalc_sigpending();
|
|
||||||
drop(guard);
|
drop(guard);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn retarget_shared_pending(pcb: Arc<ProcessControlBlock>, which: SigSet) {
|
||||||
|
let retarget = pcb.sig_info_irqsave().sig_shared_pending().signal();
|
||||||
|
retarget.intersects(which);
|
||||||
|
if retarget.is_empty() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 对于线程组中的每一个线程都要执行的函数
|
||||||
|
let thread_handling_function = |pcb: Arc<ProcessControlBlock>, retarget: &SigSet| {
|
||||||
|
if retarget.is_empty() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if pcb.flags().contains(ProcessFlags::EXITING) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let blocked = pcb.sig_info_irqsave().sig_shared_pending().signal();
|
||||||
|
if retarget.difference(blocked).is_empty() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
retarget.intersects(blocked);
|
||||||
|
if !pcb.has_pending_signal() {
|
||||||
|
let guard = pcb.sig_struct_irqsave();
|
||||||
|
signal_wake_up(pcb.clone(), guard, false);
|
||||||
|
}
|
||||||
|
// 之前的对retarget的判断移动到最前面,因为对于当前线程的线程的处理已经结束,对于后面的线程在一开始判断retarget为空即可结束处理
|
||||||
|
|
||||||
|
// debug!("handle done");
|
||||||
|
};
|
||||||
|
|
||||||
|
// 暴力遍历每一个线程,找到相同的tgid
|
||||||
|
let tgid = pcb.tgid();
|
||||||
|
for &pid in pcb.children_read_irqsave().iter() {
|
||||||
|
if let Some(child) = ProcessManager::find(pid) {
|
||||||
|
if child.tgid() == tgid {
|
||||||
|
thread_handling_function(child, &retarget);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// debug!("retarget_shared_pending done!");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 设置当前进程的屏蔽信号 (sig_block)
|
||||||
|
///
|
||||||
|
/// ## 参数
|
||||||
|
///
|
||||||
|
/// - `new_set` 新的屏蔽信号bitmap的值
|
||||||
|
pub fn set_current_blocked(new_set: &mut SigSet) {
|
||||||
|
let to_remove: SigSet =
|
||||||
|
<Signal as Into<SigSet>>::into(Signal::SIGKILL) | Signal::SIGSTOP.into();
|
||||||
|
new_set.remove(to_remove);
|
||||||
|
__set_current_blocked(new_set);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 设置当前进程的屏蔽信号 (sig_block)
|
||||||
|
///
|
||||||
|
/// ## 参数
|
||||||
|
///
|
||||||
|
/// - `how` 设置方式
|
||||||
|
/// - `new_set` 新的屏蔽信号bitmap的值
|
||||||
|
pub fn set_sigprocmask(how: SigHow, set: SigSet) -> Result<SigSet, SystemError> {
|
||||||
|
let pcb: Arc<ProcessControlBlock> = ProcessManager::current_pcb();
|
||||||
|
let guard = pcb.sig_info_irqsave();
|
||||||
|
let oset = *guard.sig_block();
|
||||||
|
|
||||||
|
let mut res_set = oset;
|
||||||
|
drop(guard);
|
||||||
|
|
||||||
|
match how {
|
||||||
|
SigHow::Block => {
|
||||||
|
// debug!("SIG_BLOCK\tGoing to insert is: {}", set.bits());
|
||||||
|
res_set.insert(set);
|
||||||
|
}
|
||||||
|
SigHow::Unblock => {
|
||||||
|
res_set.remove(set);
|
||||||
|
}
|
||||||
|
SigHow::SetMask => {
|
||||||
|
// debug!("SIG_SETMASK\tGoing to set is: {}", set.bits());
|
||||||
|
res_set = set;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
__set_current_blocked(&res_set);
|
||||||
|
Ok(oset)
|
||||||
|
}
|
||||||
|
@ -35,6 +35,7 @@ use crate::{
|
|||||||
use super::{
|
use super::{
|
||||||
pipe::{LockedPipeInode, PipeFsPrivateData},
|
pipe::{LockedPipeInode, PipeFsPrivateData},
|
||||||
shm::{ShmCtlCmd, ShmFlags, ShmId, ShmKey},
|
shm::{ShmCtlCmd, ShmFlags, ShmId, ShmKey},
|
||||||
|
signal::{set_sigprocmask, SigHow},
|
||||||
signal_types::{
|
signal_types::{
|
||||||
SaHandlerType, SigInfo, SigType, Sigaction, SigactionType, UserSigaction, USER_SIG_DFL,
|
SaHandlerType, SigInfo, SigType, Sigaction, SigactionType, UserSigaction, USER_SIG_DFL,
|
||||||
USER_SIG_ERR, USER_SIG_IGN,
|
USER_SIG_ERR, USER_SIG_IGN,
|
||||||
@ -504,4 +505,66 @@ impl Syscall {
|
|||||||
ShmCtlCmd::Default => Err(SystemError::EINVAL),
|
ShmCtlCmd::Default => Err(SystemError::EINVAL),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// # SYS_SIGPROCMASK系统调用函数,用于设置或查询当前进程的信号屏蔽字
|
||||||
|
///
|
||||||
|
/// ## 参数
|
||||||
|
///
|
||||||
|
/// - `how`: 指示如何修改信号屏蔽字
|
||||||
|
/// - `nset`: 新的信号屏蔽字
|
||||||
|
/// - `oset`: 旧的信号屏蔽字的指针,由于可以是NULL,所以用Option包装
|
||||||
|
/// - `sigsetsize`: 信号集的大小
|
||||||
|
///
|
||||||
|
/// ## 返回值
|
||||||
|
///
|
||||||
|
/// 成功:0
|
||||||
|
/// 失败:错误码
|
||||||
|
///
|
||||||
|
/// ## 说明
|
||||||
|
/// 根据 https://man7.org/linux/man-pages/man2/sigprocmask.2.html ,传进来的oldset和newset都是指针类型,这里选择传入usize然后转换为u64的指针类型
|
||||||
|
pub fn rt_sigprocmask(
|
||||||
|
how: i32,
|
||||||
|
newset: usize,
|
||||||
|
oldset: usize,
|
||||||
|
sigsetsize: usize,
|
||||||
|
) -> Result<usize, SystemError> {
|
||||||
|
// 对应oset传进来一个NULL的情况
|
||||||
|
let oset = if oldset == 0 { None } else { Some(oldset) };
|
||||||
|
let nset = if newset == 0 { None } else { Some(newset) };
|
||||||
|
|
||||||
|
if sigsetsize != size_of::<SigSet>() {
|
||||||
|
return Err(SystemError::EFAULT);
|
||||||
|
}
|
||||||
|
|
||||||
|
let sighow = SigHow::try_from(how)?;
|
||||||
|
|
||||||
|
let mut new_set = SigSet::default();
|
||||||
|
if let Some(nset) = nset {
|
||||||
|
let reader = UserBufferReader::new(
|
||||||
|
VirtAddr::new(nset).as_ptr::<u64>(),
|
||||||
|
core::mem::size_of::<u64>(),
|
||||||
|
true,
|
||||||
|
)?;
|
||||||
|
|
||||||
|
let nset = reader.read_one_from_user::<u64>(0)?;
|
||||||
|
new_set = SigSet::from_bits_truncate(*nset);
|
||||||
|
// debug!("Get Newset: {}", &new_set.bits());
|
||||||
|
let to_remove: SigSet =
|
||||||
|
<Signal as Into<SigSet>>::into(Signal::SIGKILL) | Signal::SIGSTOP.into();
|
||||||
|
new_set.remove(to_remove);
|
||||||
|
}
|
||||||
|
|
||||||
|
let oldset_to_return = set_sigprocmask(sighow, new_set)?;
|
||||||
|
if let Some(oldset) = oset {
|
||||||
|
// debug!("Get Oldset to return: {}", &oldset_to_return.bits());
|
||||||
|
let mut writer = UserBufferWriter::new(
|
||||||
|
VirtAddr::new(oldset).as_ptr::<u64>(),
|
||||||
|
core::mem::size_of::<u64>(),
|
||||||
|
true,
|
||||||
|
)?;
|
||||||
|
writer.copy_one_to_user::<u64>(&oldset_to_return.bits(), 0)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(0)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@ use system_error::SystemError;
|
|||||||
use crate::{
|
use crate::{
|
||||||
arch::ipc::signal::SigSet,
|
arch::ipc::signal::SigSet,
|
||||||
filesystem::vfs::file::FileMode,
|
filesystem::vfs::file::FileMode,
|
||||||
ipc::signal::set_current_sig_blocked,
|
ipc::signal::set_current_blocked,
|
||||||
mm::VirtAddr,
|
mm::VirtAddr,
|
||||||
syscall::{
|
syscall::{
|
||||||
user_access::{UserBufferReader, UserBufferWriter},
|
user_access::{UserBufferReader, UserBufferWriter},
|
||||||
@ -96,7 +96,7 @@ impl Syscall {
|
|||||||
sigmask: &mut SigSet,
|
sigmask: &mut SigSet,
|
||||||
) -> Result<usize, SystemError> {
|
) -> Result<usize, SystemError> {
|
||||||
// 设置屏蔽的信号
|
// 设置屏蔽的信号
|
||||||
set_current_sig_blocked(sigmask);
|
set_current_blocked(sigmask);
|
||||||
|
|
||||||
let wait_ret = Self::epoll_wait(epfd, epoll_event, max_events, timespec);
|
let wait_ret = Self::epoll_wait(epfd, epoll_event, max_events, timespec);
|
||||||
|
|
||||||
|
@ -1061,6 +1061,14 @@ impl ProcessControlBlock {
|
|||||||
fn exit_files(&self) {
|
fn exit_files(&self) {
|
||||||
self.basic.write_irqsave().set_fd_table(None);
|
self.basic.write_irqsave().set_fd_table(None);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn children_read_irqsave(&self) -> RwLockReadGuard<Vec<Pid>> {
|
||||||
|
self.children.read_irqsave()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn threads_read_irqsave(&self) -> RwLockReadGuard<ThreadInfo> {
|
||||||
|
self.thread.read_irqsave()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Drop for ProcessControlBlock {
|
impl Drop for ProcessControlBlock {
|
||||||
@ -1092,6 +1100,12 @@ pub struct ThreadInfo {
|
|||||||
group_leader: Weak<ProcessControlBlock>,
|
group_leader: Weak<ProcessControlBlock>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Default for ThreadInfo {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self::new()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl ThreadInfo {
|
impl ThreadInfo {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
|
@ -879,8 +879,11 @@ impl Syscall {
|
|||||||
}
|
}
|
||||||
|
|
||||||
SYS_RT_SIGPROCMASK => {
|
SYS_RT_SIGPROCMASK => {
|
||||||
warn!("SYS_RT_SIGPROCMASK has not yet been implemented");
|
let how = args[0] as i32;
|
||||||
Ok(0)
|
let nset = args[1];
|
||||||
|
let oset = args[2];
|
||||||
|
let sigsetsize = args[3];
|
||||||
|
Self::rt_sigprocmask(how, nset, oset, sigsetsize)
|
||||||
}
|
}
|
||||||
|
|
||||||
SYS_TKILL => {
|
SYS_TKILL => {
|
||||||
|
1
user/apps/test-sigprocmask/.gitignore
vendored
Normal file
1
user/apps/test-sigprocmask/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
test-sigprocmask
|
20
user/apps/test-sigprocmask/Makefile
Normal file
20
user/apps/test-sigprocmask/Makefile
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
ifeq ($(ARCH), x86_64)
|
||||||
|
CROSS_COMPILE=x86_64-linux-musl-
|
||||||
|
else ifeq ($(ARCH), riscv64)
|
||||||
|
CROSS_COMPILE=riscv64-linux-musl-
|
||||||
|
endif
|
||||||
|
|
||||||
|
CC=$(CROSS_COMPILE)gcc
|
||||||
|
|
||||||
|
.PHONY: all
|
||||||
|
all: main.c
|
||||||
|
$(CC) -static -o test-sigprocmask main.c
|
||||||
|
|
||||||
|
.PHONY: install clean
|
||||||
|
install: all
|
||||||
|
mv test-sigprocmask $(DADK_CURRENT_BUILD_DIR)/test-sigprocmask
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm test-sigprocmask *.o
|
||||||
|
|
||||||
|
fmt:
|
130
user/apps/test-sigprocmask/main.c
Normal file
130
user/apps/test-sigprocmask/main.c
Normal file
@ -0,0 +1,130 @@
|
|||||||
|
#include <signal.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#define TEST_ASSERT(left, right, success_msg, fail_msg) \
|
||||||
|
do { \
|
||||||
|
if ((left) == (right)) { \
|
||||||
|
printf("[PASS] %s\n", success_msg); \
|
||||||
|
} else { \
|
||||||
|
printf("[FAIL] %s: Expected 0x%lx, but got 0x%lx\n", \
|
||||||
|
fail_msg, \
|
||||||
|
(unsigned long)(right), \
|
||||||
|
(unsigned long)(left)); \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
|
||||||
|
static int signal_received = 0;
|
||||||
|
|
||||||
|
void signal_handler(int signo) {
|
||||||
|
if (signo == SIGINT) {
|
||||||
|
printf("\nReceived SIGINT (Ctrl+C)\n");
|
||||||
|
signal_received = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_signal_mask(const char *msg, const sigset_t *mask) {
|
||||||
|
printf("%s: ", msg);
|
||||||
|
for (int signo = 1; signo < NSIG; ++signo) {
|
||||||
|
if (sigismember(mask, signo)) {
|
||||||
|
printf("%d ", signo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取当前屏蔽字的函数
|
||||||
|
unsigned long get_signal_mask() {
|
||||||
|
sigset_t sigset;
|
||||||
|
if (sigprocmask(SIG_BLOCK, NULL, &sigset) == -1) {
|
||||||
|
perror("sigprocmask");
|
||||||
|
return -1; // 返回错误标记
|
||||||
|
}
|
||||||
|
|
||||||
|
// 将信号集编码为位掩码
|
||||||
|
unsigned long mask = 0;
|
||||||
|
for (int i = 1; i < NSIG; i++) {
|
||||||
|
if (sigismember(&sigset, i)) {
|
||||||
|
mask |= 1UL << (i - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return mask;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
sigset_t new_mask, old_mask;
|
||||||
|
sigemptyset(&old_mask);
|
||||||
|
|
||||||
|
// 注册 SIGINT 的信号处理函数
|
||||||
|
if (signal(SIGINT, signal_handler) == SIG_ERR) {
|
||||||
|
perror("signal");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
signal_received = 0;
|
||||||
|
kill(getpid(), SIGINT);
|
||||||
|
TEST_ASSERT(signal_received, 1, "SIGINT was received", "SIGINT was not received");
|
||||||
|
signal_received = 0;
|
||||||
|
|
||||||
|
// 初始化新的信号集,并将 SIGINT 添加到其中
|
||||||
|
sigemptyset(&new_mask);
|
||||||
|
sigaddset(&new_mask, SIGINT);
|
||||||
|
|
||||||
|
// 打印 new_mask 的值
|
||||||
|
print_signal_mask("new_mask", &new_mask);
|
||||||
|
|
||||||
|
// 屏蔽 SIGINT
|
||||||
|
if (sigprocmask(SIG_BLOCK, &new_mask, &old_mask) < 0) {
|
||||||
|
perror("sigprocmask - SIG_BLOCK");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 打印 old_mask 的值
|
||||||
|
print_signal_mask("old_mask", &old_mask);
|
||||||
|
|
||||||
|
// 检查 SIGINT 是否被屏蔽
|
||||||
|
unsigned long actual_mask = get_signal_mask();
|
||||||
|
unsigned long expected_mask = (1UL << (SIGINT - 1));
|
||||||
|
TEST_ASSERT(actual_mask,
|
||||||
|
expected_mask,
|
||||||
|
"Signal mask is as expected",
|
||||||
|
"Signal mask mismatch");
|
||||||
|
|
||||||
|
printf("SIGINT is now blocked.\n");
|
||||||
|
signal_received = 0;
|
||||||
|
// 向当前进程发送 SIGINT
|
||||||
|
kill(getpid(), SIGINT);
|
||||||
|
|
||||||
|
// 等待 5 秒,以便测试 SIGINT 是否被屏蔽
|
||||||
|
sleep(5);
|
||||||
|
TEST_ASSERT(signal_received, 0, "SIGINT was blocked", "SIGINT was not blocked");
|
||||||
|
signal_received = 0;
|
||||||
|
// 恢复原来的信号屏蔽字
|
||||||
|
if (sigprocmask(SIG_SETMASK, &old_mask, &old_mask) < 0) {
|
||||||
|
perror("sigprocmask - SIG_SETMASK");
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
print_signal_mask("old_mask returned", &old_mask);
|
||||||
|
|
||||||
|
// 检查 SIGINT 是否被解除屏蔽
|
||||||
|
actual_mask = get_signal_mask();
|
||||||
|
expected_mask = 0;
|
||||||
|
TEST_ASSERT(actual_mask,
|
||||||
|
expected_mask,
|
||||||
|
"Signal mask is as expected",
|
||||||
|
"Signal mask mismatch");
|
||||||
|
|
||||||
|
printf("SIGINT is now unblocked.\n");
|
||||||
|
|
||||||
|
signal_received = 0;
|
||||||
|
kill(getpid(), SIGINT);
|
||||||
|
|
||||||
|
// 等待 5 秒,以便测试 SIGINT 是否解除屏蔽
|
||||||
|
sleep(5);
|
||||||
|
TEST_ASSERT(signal_received, 1, "SIGINT was received", "SIGINT was not received");
|
||||||
|
|
||||||
|
printf("Exiting program.\n");
|
||||||
|
return 0;
|
||||||
|
}
|
41
user/dadk/config/test_sigprocmask_0_1_0.toml
Normal file
41
user/dadk/config/test_sigprocmask_0_1_0.toml
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
# 用户程序名称
|
||||||
|
name = "test_sigprocmask"
|
||||||
|
# 版本号
|
||||||
|
version = "0.1.0"
|
||||||
|
# 用户程序描述信息
|
||||||
|
description = "一个用来测试sigprocmask能够正常运行的app"
|
||||||
|
# (可选)默认: false 是否只构建一次,如果为true,DADK会在构建成功后,将构建结果缓存起来,下次构建时,直接使用缓存的构建结果
|
||||||
|
build-once = false
|
||||||
|
# (可选) 默认: false 是否只安装一次,如果为true,DADK会在安装成功后,不再重复安装
|
||||||
|
install-once = false
|
||||||
|
# 目标架构
|
||||||
|
# 可选值:"x86_64", "aarch64", "riscv64"
|
||||||
|
target-arch = ["x86_64"]
|
||||||
|
# 任务源
|
||||||
|
[task-source]
|
||||||
|
# 构建类型
|
||||||
|
# 可选值:"build-from_source", "install-from-prebuilt"
|
||||||
|
type = "build-from-source"
|
||||||
|
# 构建来源
|
||||||
|
# "build_from_source" 可选值:"git", "local", "archive"
|
||||||
|
# "install_from_prebuilt" 可选值:"local", "archive"
|
||||||
|
source = "local"
|
||||||
|
# 路径或URL
|
||||||
|
source-path = "user/apps/test-sigprocmask"
|
||||||
|
# 构建相关信息
|
||||||
|
[build]
|
||||||
|
# (可选)构建命令
|
||||||
|
build-command = "make install"
|
||||||
|
# 安装相关信息
|
||||||
|
[install]
|
||||||
|
# (可选)安装到DragonOS的路径
|
||||||
|
in-dragonos-path = "/bin"
|
||||||
|
# 清除相关信息
|
||||||
|
[clean]
|
||||||
|
# (可选)清除命令
|
||||||
|
clean-command = "make clean"
|
||||||
|
# (可选)依赖项
|
||||||
|
# 注意:如果没有依赖项,忽略此项,不允许只留一个[[depends]]
|
||||||
|
# 由于原文件中依赖项为空,此处省略[[depends]]部分
|
||||||
|
# (可选)环境变量
|
||||||
|
# 由于原文件中环境变量为空,此处省略[[envs]]部分
|
Loading…
x
Reference in New Issue
Block a user