Add sigaction struct and sys_call

ch7-signal
liusm18 3 years ago
parent 598d8d4538
commit fae8641f36

@ -21,6 +21,8 @@ mod process;
use fs::*;
use process::*;
use crate::task::SignalAction;
pub fn syscall(syscall_id: usize, args: [usize; 3]) -> isize {
match syscall_id {
SYSCALL_DUP => sys_dup(args[0]),
@ -32,7 +34,7 @@ pub fn syscall(syscall_id: usize, args: [usize; 3]) -> isize {
SYSCALL_EXIT => sys_exit(args[0] as i32),
SYSCALL_YIELD => sys_yield(),
SYSCALL_KILL => sys_kill(args[0], args[1] as u32),
SYSCALL_SIGACTION => sys_sigation(args[0] as u32, args[1], args[2]),
SYSCALL_SIGACTION => sys_sigaction(args[0] as u32, args[1] as *const SignalAction, args[2] as *mut SignalAction),
SYSCALL_SIGPROCMASK => sys_sigprocmask(args[0] as u32),
SYSCALL_GET_TIME => sys_get_time(),
SYSCALL_GETPID => sys_getpid(),

@ -2,7 +2,7 @@ use crate::fs::{open_file, OpenFlags};
use crate::mm::{translated_ref, translated_refmut, translated_str};
use crate::task::{
add_task, current_task, current_user_token, exit_current_and_run_next, pid2task,
suspend_current_and_run_next, SignalFlags,
suspend_current_and_run_next, SignalFlags, SignalAction,
};
use crate::timer::get_time_ms;
use alloc::string::String;
@ -109,10 +109,10 @@ pub fn sys_kill(pid: usize, signal: u32) -> isize {
if let Some(flag) = SignalFlags::from_bits(signal) {
// insert the signal if legal
let mut task_ref = task.inner_exclusive_access();
if task_ref.pending_signals.contains(flag) {
if task_ref.signals.contains(flag) {
return -1;
}
task_ref.pending_signals.insert(flag);
task_ref.signals.insert(flag);
0
} else {
-1
@ -137,6 +137,34 @@ pub fn sys_sigprocmask(mask: u32) -> isize {
}
}
pub fn sys_sigation(_signal: u32, _action: usize, _old_action: usize) -> isize {
0
fn check_sigaction_error(signal: SignalFlags, action: usize, old_action: usize) -> bool {
if action == 0 || old_action == 0 || signal == SignalFlags::SIGKILL ||
signal == SignalFlags::SIGSTOP {
true
} else {
false
}
}
pub fn sys_sigaction(signal: u32, action: *const SignalAction, old_action: *mut SignalAction) -> isize {
let token = current_user_token();
if let Some(task) = current_task() {
let mut inner = task.inner_exclusive_access();
if let Some(flag) = SignalFlags::from_bits(signal) {
if check_sigaction_error(flag, action as usize, old_action as usize) {
return -1;
}
let old_kernel_action = inner.signal_actions.table[signal as usize];
if old_kernel_action.mask != SignalFlags::from_bits(40).unwrap() {
*translated_refmut(token, old_action) = old_kernel_action;
} else {
let mut ref_old_action = *translated_refmut(token, old_action);
ref_old_action.handler = old_kernel_action.handler;
}
let ref_action = translated_ref(token, action);
inner.signal_actions.table[signal as usize] = *ref_action;
return 0;
}
}
-1
}

@ -0,0 +1,32 @@
use crate::task::{SignalFlags, MAX_SIG};
/// Action for a signal
#[repr(C)]
#[derive(Debug, Clone, Copy)]
pub struct SignalAction {
pub handler: usize,
pub mask: SignalFlags
}
impl Default for SignalAction {
fn default() -> Self {
Self {
handler: 0,
mask: SignalFlags::from_bits(40).unwrap()
}
}
}
#[derive(Clone)]
pub struct SignalActions {
pub table: [SignalAction; MAX_SIG + 1],
}
impl Default for SignalActions {
fn default() -> Self {
Self {
table: [SignalAction::default(); MAX_SIG + 1],
}
}
}

@ -4,6 +4,7 @@ mod pid;
mod processor;
mod signal;
mod switch;
mod action;
#[allow(clippy::module_inception)]
mod task;
@ -21,7 +22,8 @@ pub use pid::{pid_alloc, KernelStack, PidHandle};
pub use processor::{
current_task, current_trap_cx, current_user_token, run_tasks, schedule, take_current_task,
};
pub use signal::SignalFlags;
pub use signal::{SignalFlags, MAX_SIG};
pub use action::{SignalAction, SignalActions};
pub fn suspend_current_and_run_next() {
// There must be an application running.

@ -1,5 +1,7 @@
use bitflags::*;
pub const MAX_SIG: usize = 31;
bitflags! {
pub struct SignalFlags: u32 {
const SIGHUP = 1 << 1;

@ -1,4 +1,4 @@
use super::TaskContext;
use super::{TaskContext, SignalActions};
use super::{pid_alloc, KernelStack, PidHandle, SignalFlags};
use crate::config::TRAP_CONTEXT;
use crate::fs::{File, Stdin, Stdout};
@ -30,8 +30,11 @@ pub struct TaskControlBlockInner {
pub exit_code: i32,
pub fd_table: Vec<Option<Arc<dyn File + Send + Sync>>>,
pub signals: SignalFlags,
pub pending_signals: SignalFlags,
pub signal_mask: SignalFlags
pub signal_mask: SignalFlags,
// if a the task is handling a signal
pub handling_flag: bool,
// Signal actions
pub signal_actions: SignalActions
}
impl TaskControlBlockInner {
@ -94,8 +97,9 @@ impl TaskControlBlock {
Some(Arc::new(Stdout)),
],
signals: SignalFlags::empty(),
pending_signals: SignalFlags::empty(),
signal_mask: SignalFlags::empty()
signal_mask: SignalFlags::empty(),
handling_flag: false,
signal_actions: SignalActions::default()
})
},
};
@ -198,8 +202,10 @@ impl TaskControlBlock {
exit_code: 0,
fd_table: new_fd_table,
signals: SignalFlags::empty(),
pending_signals: SignalFlags::empty(),
signal_mask: SignalFlags::empty()
// inherit the signal_mask and signal_action
signal_mask: parent_inner.signal_mask,
handling_flag: false,
signal_actions: parent_inner.signal_actions.clone()
})
},
});

Loading…
Cancel
Save