kernel_thread/syscall/
signal.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
//! 信号相关的系统调用
//!
//!

use libc_core::{
    internal::SigAction,
    signal::SignalNum,
    types::{SigMaskHow, SigSet},
};
use sel4::UserContext;
use syscalls::Errno;
use zerocopy::{FromBytes, IntoBytes};

use crate::{child_test::TASK_MAP, task::Sel4Task};

use super::SysResult;

pub(super) fn sys_sigprocmask(
    task: &Sel4Task,
    how: u8,
    set: *const SigSet,
    old: *mut SigSet,
) -> SysResult {
    if !old.is_null() {
        task.write_bytes(old as _, task.signal.lock().mask.as_bytes());
    }
    if !set.is_null() {
        let sigproc_bytes = task.read_bytes(set as _, size_of::<SigSet>()).unwrap();
        let maskset = &mut SigSet::ref_from_bytes(&sigproc_bytes).unwrap();
        let sighow = SigMaskHow::try_from(how).or(Err(Errno::EINVAL))?;
        task.signal.lock().mask.handle(sighow, maskset);
    }
    Ok(0)
}

pub(super) fn sys_sigaction(
    task: &Sel4Task,
    sig: usize,
    act: *const SigAction,
    oldact: *mut SigAction,
) -> SysResult {
    if !oldact.is_null() {
        task.write_bytes(
            oldact as _,
            task.signal.lock().actions.lock()[sig].as_bytes(),
        );
    }

    if !act.is_null() {
        let sigaction_bytes = task.read_bytes(act as _, size_of::<SigAction>()).unwrap();
        let sigact = SigAction::ref_from_bytes(&sigaction_bytes).unwrap();
        task.signal.lock().actions.lock()[sig] = sigact.clone();
    }
    Ok(0)
}

pub(super) fn sys_kill(task: &Sel4Task, pid: usize, sig: usize) -> SysResult {
    let target = TASK_MAP
        .lock()
        .get(&(pid as _))
        .ok_or(Errno::ESRCH)?
        .clone();
    if sig == 0 {
        return Ok(0);
    }
    target.add_signal(SignalNum::from_num(sig).ok_or(Errno::EINVAL)?, task.tid);
    Ok(0)
}

pub(super) fn sys_sigreturn(task: &Sel4Task, ctx: &mut UserContext) -> SysResult {
    task.read_ucontext(ctx);
    *ctx.pc_mut() -= 4;
    Ok(*ctx.c_param(0) as _)
}

pub(super) fn sys_sigtimedwait(_task: &Sel4Task) -> SysResult {
    debug!("sys_sigtimedwait @ ");
    // WaitSignal(self.task.clone()).await;
    // let task = current_user_task();
    // task.inner_map(|x| x.signal.has_signal());
    // Err(LinuxError::EAGAIN)
    Ok(0)
}