mirror of
https://github.com/rcore-os/rCore-Tutorial-v3.git
synced 2024-11-23 01:46:24 +04:00
Add signal user lib
This commit is contained in:
parent
1d7b8141f0
commit
7a97faee6c
@ -35,7 +35,7 @@ pub fn syscall(syscall_id: usize, args: [usize; 3]) -> isize {
|
|||||||
SYSCALL_EXIT => sys_exit(args[0] as i32),
|
SYSCALL_EXIT => sys_exit(args[0] as i32),
|
||||||
SYSCALL_YIELD => sys_yield(),
|
SYSCALL_YIELD => sys_yield(),
|
||||||
SYSCALL_KILL => sys_kill(args[0], args[1] as u32),
|
SYSCALL_KILL => sys_kill(args[0], args[1] as u32),
|
||||||
SYSCALL_SIGACTION => sys_sigaction(args[0] as u32, args[1] as *const SignalAction, args[2] as *mut SignalAction),
|
SYSCALL_SIGACTION => sys_sigaction(args[0], args[1] as *const SignalAction, args[2] as *mut SignalAction),
|
||||||
SYSCALL_SIGPROCMASK => sys_sigprocmask(args[0] as u32),
|
SYSCALL_SIGPROCMASK => sys_sigprocmask(args[0] as u32),
|
||||||
SYSCALL_SIGRETURN => sys_sigretrun(),
|
SYSCALL_SIGRETURN => sys_sigretrun(),
|
||||||
SYSCALL_GET_TIME => sys_get_time(),
|
SYSCALL_GET_TIME => sys_get_time(),
|
||||||
|
@ -2,7 +2,7 @@ use crate::fs::{open_file, OpenFlags};
|
|||||||
use crate::mm::{translated_ref, translated_refmut, translated_str};
|
use crate::mm::{translated_ref, translated_refmut, translated_str};
|
||||||
use crate::task::{
|
use crate::task::{
|
||||||
add_task, current_task, current_user_token, exit_current_and_run_next, pid2task,
|
add_task, current_task, current_user_token, exit_current_and_run_next, pid2task,
|
||||||
suspend_current_and_run_next, SignalFlags, SignalAction,
|
suspend_current_and_run_next, SignalFlags, SignalAction, MAX_SIG,
|
||||||
};
|
};
|
||||||
use crate::timer::get_time_ms;
|
use crate::timer::get_time_ms;
|
||||||
use alloc::string::String;
|
use alloc::string::String;
|
||||||
@ -159,15 +159,18 @@ fn check_sigaction_error(signal: SignalFlags, action: usize, old_action: usize)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn sys_sigaction(signal: u32, action: *const SignalAction, old_action: *mut SignalAction) -> isize {
|
pub fn sys_sigaction(signum: usize, action: *const SignalAction, old_action: *mut SignalAction) -> isize {
|
||||||
let token = current_user_token();
|
let token = current_user_token();
|
||||||
if let Some(task) = current_task() {
|
if let Some(task) = current_task() {
|
||||||
let mut inner = task.inner_exclusive_access();
|
let mut inner = task.inner_exclusive_access();
|
||||||
if let Some(flag) = SignalFlags::from_bits(signal) {
|
if signum as usize > MAX_SIG {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if let Some(flag) = SignalFlags::from_bits(1 << signum) {
|
||||||
if check_sigaction_error(flag, action as usize, old_action as usize) {
|
if check_sigaction_error(flag, action as usize, old_action as usize) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
let old_kernel_action = inner.signal_actions.table[signal as usize];
|
let old_kernel_action = inner.signal_actions.table[signum];
|
||||||
if old_kernel_action.mask != SignalFlags::from_bits(40).unwrap() {
|
if old_kernel_action.mask != SignalFlags::from_bits(40).unwrap() {
|
||||||
*translated_refmut(token, old_action) = old_kernel_action;
|
*translated_refmut(token, old_action) = old_kernel_action;
|
||||||
} else {
|
} else {
|
||||||
@ -175,7 +178,7 @@ pub fn sys_sigaction(signal: u32, action: *const SignalAction, old_action: *mut
|
|||||||
ref_old_action.handler = old_kernel_action.handler;
|
ref_old_action.handler = old_kernel_action.handler;
|
||||||
}
|
}
|
||||||
let ref_action = translated_ref(token, action);
|
let ref_action = translated_ref(token, action);
|
||||||
inner.signal_actions.table[signal as usize] = *ref_action;
|
inner.signal_actions.table[signum] = *ref_action;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
158
user/src/bin/sig_tests.rs
Normal file
158
user/src/bin/sig_tests.rs
Normal file
@ -0,0 +1,158 @@
|
|||||||
|
#![no_std]
|
||||||
|
#![no_main]
|
||||||
|
|
||||||
|
#[macro_use]
|
||||||
|
extern crate user_lib;
|
||||||
|
|
||||||
|
use user_lib::{sigaction, sigprocmask, SignalAction, SignalFlags, fork, exit, wait, kill, getpid, sleep};
|
||||||
|
|
||||||
|
fn func() {
|
||||||
|
println!("user_sig_test succsess");
|
||||||
|
}
|
||||||
|
|
||||||
|
fn user_sig_test_failsignum() {
|
||||||
|
let mut new = SignalAction::default();
|
||||||
|
let old = SignalAction::default();
|
||||||
|
new.handler = func as usize;
|
||||||
|
if sigaction(50, &new, &old) >= 0 {
|
||||||
|
panic!("Wrong sigaction but success!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn user_sig_test_kill() {
|
||||||
|
let mut new = SignalAction::default();
|
||||||
|
let old = SignalAction::default();
|
||||||
|
new.handler = func as usize;
|
||||||
|
|
||||||
|
if sigaction(10, &new, &old) < 0 {
|
||||||
|
panic!("Sigaction failed!");
|
||||||
|
}
|
||||||
|
if kill(getpid() as usize, 1 << 10) < 0 {
|
||||||
|
println!("Kill failed!");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn user_sig_test_multiprocsignals() {
|
||||||
|
let pid= fork();
|
||||||
|
if pid == 0{
|
||||||
|
let mut new = SignalAction::default();
|
||||||
|
let old = SignalAction::default();
|
||||||
|
new.handler = func as usize;
|
||||||
|
if sigaction(10, &new, &old) < 0 {
|
||||||
|
panic!("Sigaction failed!");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if kill(pid as usize, 1 << 10) < 0 {
|
||||||
|
println!("Kill failed!");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
let mut exit_code = 0;
|
||||||
|
wait(&mut exit_code);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn user_sig_test_restore() {
|
||||||
|
let mut new = SignalAction::default();
|
||||||
|
let old = SignalAction::default();
|
||||||
|
let old2 = SignalAction::default();
|
||||||
|
new.handler = func as usize;
|
||||||
|
|
||||||
|
if sigaction(10, &new, &old) < 0 {
|
||||||
|
panic!("Sigaction failed!");
|
||||||
|
}
|
||||||
|
|
||||||
|
if sigaction(10, &old, &old2) < 0 {
|
||||||
|
panic!("Sigaction failed!");
|
||||||
|
}
|
||||||
|
|
||||||
|
if old2.handler != new.handler {
|
||||||
|
println!("Restore failed!");
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn kernel_sig_test_ignore() {
|
||||||
|
sigprocmask(SignalFlags::SIGSTOP.bits() as u32);
|
||||||
|
if kill(getpid() as usize, SignalFlags::SIGSTOP.bits()) < 0{
|
||||||
|
println!("kill faild\n");
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn kernel_sig_test_stop_cont() {
|
||||||
|
let pid= fork();
|
||||||
|
if pid == 0 {
|
||||||
|
kill(getpid() as usize, SignalFlags::SIGSTOP.bits());
|
||||||
|
sleep(1000);
|
||||||
|
exit(-1);
|
||||||
|
} else {
|
||||||
|
sleep(5000);
|
||||||
|
kill(pid as usize, SignalFlags::SIGCONT.bits());
|
||||||
|
let mut exit_code = 0;
|
||||||
|
wait(&mut exit_code);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn kernel_sig_test_failignorekill() {
|
||||||
|
let mut new = SignalAction::default();
|
||||||
|
let old = SignalAction::default();
|
||||||
|
new.handler = func as usize;
|
||||||
|
|
||||||
|
if sigaction(9, &new, &old) >= 0 {
|
||||||
|
panic!("Should not set sigaction to kill!");
|
||||||
|
}
|
||||||
|
|
||||||
|
if sigaction(9, &new, 0 as *const SignalAction) >= 0 {
|
||||||
|
panic!("Should not set sigaction to kill!");
|
||||||
|
}
|
||||||
|
|
||||||
|
if sigaction(9, 0 as *const SignalAction, &old) >= 0 {
|
||||||
|
panic!("Should not set sigaction to kill!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fn run(f: fn()) -> bool {
|
||||||
|
let pid = fork();
|
||||||
|
if pid == 0 {
|
||||||
|
f();
|
||||||
|
exit(0);
|
||||||
|
} else {
|
||||||
|
let mut exit_code: i32 = 0;
|
||||||
|
wait(&mut exit_code);
|
||||||
|
if exit_code != 0 {
|
||||||
|
println!("FAILED!");
|
||||||
|
} else {
|
||||||
|
println!("OK!");
|
||||||
|
}
|
||||||
|
exit_code == 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub fn main() -> i32 {
|
||||||
|
let tests: [(fn(), &str); 7] = [
|
||||||
|
(user_sig_test_failsignum, "user_sig_test_failsignum"),
|
||||||
|
(user_sig_test_kill, "user_sig_test_kill"),
|
||||||
|
(user_sig_test_multiprocsignals, "user_sig_test_multiprocsignals"),
|
||||||
|
(user_sig_test_restore, "user_sig_test_restore"),
|
||||||
|
(kernel_sig_test_ignore, "kernel_sig_test_ignore"),
|
||||||
|
(kernel_sig_test_stop_cont, "kernel_sig_test_stop_cont"),
|
||||||
|
(kernel_sig_test_failignorekill, "kernel_sig_test_failignorekill")
|
||||||
|
];
|
||||||
|
let mut fail_num = 0;
|
||||||
|
for test in tests {
|
||||||
|
println!("Testing {}", test.1);
|
||||||
|
if !run(test.0) {
|
||||||
|
fail_num += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if fail_num == 0 {
|
||||||
|
println!("ALL TESTS PASSED");
|
||||||
|
0
|
||||||
|
} else {
|
||||||
|
println!("SOME TESTS FAILED");
|
||||||
|
-1
|
||||||
|
}
|
||||||
|
}
|
@ -139,16 +139,68 @@ pub fn sleep(period_ms: usize) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// 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::empty()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bitflags! {
|
bitflags! {
|
||||||
pub struct SignalFlags: i32 {
|
pub struct SignalFlags: i32 {
|
||||||
|
const SIGDEF = 1; // Default signal handling
|
||||||
|
const SIGHUP = 1 << 1;
|
||||||
const SIGINT = 1 << 2;
|
const SIGINT = 1 << 2;
|
||||||
|
const SIGQUIT = 1 << 3;
|
||||||
const SIGILL = 1 << 4;
|
const SIGILL = 1 << 4;
|
||||||
|
const SIGTRAP = 1 << 5;
|
||||||
const SIGABRT = 1 << 6;
|
const SIGABRT = 1 << 6;
|
||||||
|
const SIGBUS = 1 << 7;
|
||||||
const SIGFPE = 1 << 8;
|
const SIGFPE = 1 << 8;
|
||||||
|
const SIGKILL = 1 << 9;
|
||||||
|
const SIGUSR1 = 1 << 10;
|
||||||
const SIGSEGV = 1 << 11;
|
const SIGSEGV = 1 << 11;
|
||||||
|
const SIGUSR2 = 1 << 12;
|
||||||
|
const SIGPIPE = 1 << 13;
|
||||||
|
const SIGALRM = 1 << 14;
|
||||||
|
const SIGTERM = 1 << 15;
|
||||||
|
const SIGSTKFLT = 1 << 16;
|
||||||
|
const SIGCHLD = 1 << 17;
|
||||||
|
const SIGCONT = 1 << 18;
|
||||||
|
const SIGSTOP = 1 << 19;
|
||||||
|
const SIGTSTP = 1 << 20;
|
||||||
|
const SIGTTIN = 1 << 21;
|
||||||
|
const SIGTTOU = 1 << 22;
|
||||||
|
const SIGURG = 1 << 23;
|
||||||
|
const SIGXCPU = 1 << 24;
|
||||||
|
const SIGXFSZ = 1 << 25;
|
||||||
|
const SIGVTALRM = 1 << 26;
|
||||||
|
const SIGPROF = 1 << 27;
|
||||||
|
const SIGWINCH = 1 << 28;
|
||||||
|
const SIGIO = 1 << 29;
|
||||||
|
const SIGPWR = 1 << 30;
|
||||||
|
const SIGSYS = 1 << 31;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn kill(pid: usize, signal: i32) -> isize {
|
pub fn kill(pid: usize, signal: i32) -> isize {
|
||||||
sys_kill(pid, signal)
|
sys_kill(pid, signal)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn sigaction(signum: usize, action: *const SignalAction, old_action: *const SignalAction) -> isize {
|
||||||
|
sys_sigaction(signum, action, old_action)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn sigprocmask(mask: u32) -> isize {
|
||||||
|
sys_sigprocmask(mask)
|
||||||
|
}
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
use core::arch::asm;
|
use core::arch::asm;
|
||||||
|
|
||||||
|
use crate::SignalAction;
|
||||||
|
|
||||||
const SYSCALL_DUP: usize = 24;
|
const SYSCALL_DUP: usize = 24;
|
||||||
const SYSCALL_OPEN: usize = 56;
|
const SYSCALL_OPEN: usize = 56;
|
||||||
const SYSCALL_CLOSE: usize = 57;
|
const SYSCALL_CLOSE: usize = 57;
|
||||||
@ -9,6 +11,8 @@ const SYSCALL_WRITE: usize = 64;
|
|||||||
const SYSCALL_EXIT: usize = 93;
|
const SYSCALL_EXIT: usize = 93;
|
||||||
const SYSCALL_YIELD: usize = 124;
|
const SYSCALL_YIELD: usize = 124;
|
||||||
const SYSCALL_KILL: usize = 129;
|
const SYSCALL_KILL: usize = 129;
|
||||||
|
const SYSCALL_SIGACTION: usize = 134;
|
||||||
|
const SYSCALL_SIGPROCMASK: usize = 135;
|
||||||
const SYSCALL_GET_TIME: usize = 169;
|
const SYSCALL_GET_TIME: usize = 169;
|
||||||
const SYSCALL_GETPID: usize = 172;
|
const SYSCALL_GETPID: usize = 172;
|
||||||
const SYSCALL_FORK: usize = 220;
|
const SYSCALL_FORK: usize = 220;
|
||||||
@ -91,3 +95,11 @@ pub fn sys_exec(path: &str, args: &[*const u8]) -> isize {
|
|||||||
pub fn sys_waitpid(pid: isize, exit_code: *mut i32) -> isize {
|
pub fn sys_waitpid(pid: isize, exit_code: *mut i32) -> isize {
|
||||||
syscall(SYSCALL_WAITPID, [pid as usize, exit_code as usize, 0])
|
syscall(SYSCALL_WAITPID, [pid as usize, exit_code as usize, 0])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn sys_sigaction(signum: usize, action: *const SignalAction, old_action: *const SignalAction) -> isize {
|
||||||
|
syscall(SYSCALL_SIGACTION, [signum, action as usize, old_action as usize])
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn sys_sigprocmask(mask: u32) -> isize {
|
||||||
|
syscall(SYSCALL_SIGPROCMASK, [mask as usize, 0, 0])
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user