mirror of
https://github.com/rcore-os/rCore-Tutorial-v3.git
synced 2024-11-22 09:26:26 +04:00
Support signal mechanism for ch8(only works on signal-thread apps)
This commit is contained in:
parent
29d6d26644
commit
6f09af2c0f
@ -7,6 +7,7 @@ const SYSCALL_WRITE: usize = 64;
|
|||||||
const SYSCALL_EXIT: usize = 93;
|
const SYSCALL_EXIT: usize = 93;
|
||||||
const SYSCALL_SLEEP: usize = 101;
|
const SYSCALL_SLEEP: usize = 101;
|
||||||
const SYSCALL_YIELD: usize = 124;
|
const SYSCALL_YIELD: usize = 124;
|
||||||
|
const SYSCALL_KILL: usize = 129;
|
||||||
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;
|
||||||
@ -46,6 +47,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_SLEEP => sys_sleep(args[0]),
|
SYSCALL_SLEEP => sys_sleep(args[0]),
|
||||||
SYSCALL_YIELD => sys_yield(),
|
SYSCALL_YIELD => sys_yield(),
|
||||||
|
SYSCALL_KILL => sys_kill(args[0], args[1] as u32),
|
||||||
SYSCALL_GET_TIME => sys_get_time(),
|
SYSCALL_GET_TIME => sys_get_time(),
|
||||||
SYSCALL_GETPID => sys_getpid(),
|
SYSCALL_GETPID => sys_getpid(),
|
||||||
SYSCALL_FORK => sys_fork(),
|
SYSCALL_FORK => sys_fork(),
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
use crate::fs::{open_file, OpenFlags};
|
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::{
|
||||||
current_process, current_task, current_user_token, exit_current_and_run_next,
|
current_process, current_task, current_user_token, exit_current_and_run_next, pid2process,
|
||||||
suspend_current_and_run_next,
|
suspend_current_and_run_next, SignalFlags,
|
||||||
};
|
};
|
||||||
use crate::timer::get_time_ms;
|
use crate::timer::get_time_ms;
|
||||||
use alloc::string::String;
|
use alloc::string::String;
|
||||||
@ -103,3 +103,16 @@ pub fn sys_waitpid(pid: isize, exit_code_ptr: *mut i32) -> isize {
|
|||||||
}
|
}
|
||||||
// ---- release current PCB automatically
|
// ---- release current PCB automatically
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn sys_kill(pid: usize, signal: u32) -> isize {
|
||||||
|
if let Some(process) = pid2process(pid) {
|
||||||
|
if let Some(flag) = SignalFlags::from_bits(signal) {
|
||||||
|
process.inner_exclusive_access().signals |= flag;
|
||||||
|
0
|
||||||
|
} else {
|
||||||
|
-1
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
-1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use super::TaskControlBlock;
|
use super::{ProcessControlBlock, TaskControlBlock};
|
||||||
use crate::sync::UPSafeCell;
|
use crate::sync::UPSafeCell;
|
||||||
use alloc::collections::VecDeque;
|
use alloc::collections::{BTreeMap, VecDeque};
|
||||||
use alloc::sync::Arc;
|
use alloc::sync::Arc;
|
||||||
use lazy_static::*;
|
use lazy_static::*;
|
||||||
|
|
||||||
@ -26,6 +26,8 @@ impl TaskManager {
|
|||||||
lazy_static! {
|
lazy_static! {
|
||||||
pub static ref TASK_MANAGER: UPSafeCell<TaskManager> =
|
pub static ref TASK_MANAGER: UPSafeCell<TaskManager> =
|
||||||
unsafe { UPSafeCell::new(TaskManager::new()) };
|
unsafe { UPSafeCell::new(TaskManager::new()) };
|
||||||
|
pub static ref PID2PCB: UPSafeCell<BTreeMap<usize, Arc<ProcessControlBlock>>> =
|
||||||
|
unsafe { UPSafeCell::new(BTreeMap::new()) };
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_task(task: Arc<TaskControlBlock>) {
|
pub fn add_task(task: Arc<TaskControlBlock>) {
|
||||||
@ -35,3 +37,19 @@ pub fn add_task(task: Arc<TaskControlBlock>) {
|
|||||||
pub fn fetch_task() -> Option<Arc<TaskControlBlock>> {
|
pub fn fetch_task() -> Option<Arc<TaskControlBlock>> {
|
||||||
TASK_MANAGER.exclusive_access().fetch()
|
TASK_MANAGER.exclusive_access().fetch()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn pid2process(pid: usize) -> Option<Arc<ProcessControlBlock>> {
|
||||||
|
let map = PID2PCB.exclusive_access();
|
||||||
|
map.get(&pid).map(|task| Arc::clone(task))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn insert_into_pid2process(pid: usize, process: Arc<ProcessControlBlock>) {
|
||||||
|
PID2PCB.exclusive_access().insert(pid, process);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn remove_from_pid2process(pid: usize) {
|
||||||
|
let mut map = PID2PCB.exclusive_access();
|
||||||
|
if map.remove(&pid).is_none() {
|
||||||
|
panic!("cannot find pid {} in pid2task!", pid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -3,6 +3,7 @@ mod id;
|
|||||||
mod manager;
|
mod manager;
|
||||||
mod process;
|
mod process;
|
||||||
mod processor;
|
mod processor;
|
||||||
|
mod signal;
|
||||||
mod switch;
|
mod switch;
|
||||||
mod task;
|
mod task;
|
||||||
|
|
||||||
@ -15,11 +16,12 @@ use switch::__switch;
|
|||||||
|
|
||||||
pub use context::TaskContext;
|
pub use context::TaskContext;
|
||||||
pub use id::{kstack_alloc, pid_alloc, KernelStack, PidHandle};
|
pub use id::{kstack_alloc, pid_alloc, KernelStack, PidHandle};
|
||||||
pub use manager::add_task;
|
pub use manager::{add_task, pid2process, remove_from_pid2process};
|
||||||
pub use processor::{
|
pub use processor::{
|
||||||
current_kstack_top, current_process, current_task, current_trap_cx, current_trap_cx_user_va,
|
current_kstack_top, current_process, current_task, current_trap_cx, current_trap_cx_user_va,
|
||||||
current_user_token, run_tasks, schedule, take_current_task,
|
current_user_token, run_tasks, schedule, take_current_task,
|
||||||
};
|
};
|
||||||
|
pub use signal::SignalFlags;
|
||||||
pub use task::{TaskControlBlock, TaskStatus};
|
pub use task::{TaskControlBlock, TaskStatus};
|
||||||
|
|
||||||
pub fn suspend_current_and_run_next() {
|
pub fn suspend_current_and_run_next() {
|
||||||
@ -64,6 +66,7 @@ pub fn exit_current_and_run_next(exit_code: i32) {
|
|||||||
// however, if this is the main thread of current process
|
// however, if this is the main thread of current process
|
||||||
// the process should terminate at once
|
// the process should terminate at once
|
||||||
if tid == 0 {
|
if tid == 0 {
|
||||||
|
remove_from_pid2process(process.getpid());
|
||||||
let mut process_inner = process.inner_exclusive_access();
|
let mut process_inner = process.inner_exclusive_access();
|
||||||
// mark this process as a zombie process
|
// mark this process as a zombie process
|
||||||
process_inner.is_zombie = true;
|
process_inner.is_zombie = true;
|
||||||
@ -111,3 +114,15 @@ lazy_static! {
|
|||||||
pub fn add_initproc() {
|
pub fn add_initproc() {
|
||||||
let _initproc = INITPROC.clone();
|
let _initproc = INITPROC.clone();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn check_signals_of_current() -> Option<(i32, &'static str)> {
|
||||||
|
let process = current_process();
|
||||||
|
let process_inner = process.inner_exclusive_access();
|
||||||
|
process_inner.signals.check_error()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn current_add_signal(signal: SignalFlags) {
|
||||||
|
let process = current_process();
|
||||||
|
let mut process_inner = process.inner_exclusive_access();
|
||||||
|
process_inner.signals |= signal;
|
||||||
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
use super::add_task;
|
|
||||||
use super::id::RecycleAllocator;
|
use super::id::RecycleAllocator;
|
||||||
|
use super::manager::insert_into_pid2process;
|
||||||
use super::TaskControlBlock;
|
use super::TaskControlBlock;
|
||||||
|
use super::{add_task, SignalFlags};
|
||||||
use super::{pid_alloc, PidHandle};
|
use super::{pid_alloc, PidHandle};
|
||||||
use crate::fs::{File, Stdin, Stdout};
|
use crate::fs::{File, Stdin, Stdout};
|
||||||
use crate::mm::{translated_refmut, MemorySet, KERNEL_SPACE};
|
use crate::mm::{translated_refmut, MemorySet, KERNEL_SPACE};
|
||||||
@ -26,6 +27,7 @@ pub struct ProcessControlBlockInner {
|
|||||||
pub children: Vec<Arc<ProcessControlBlock>>,
|
pub children: Vec<Arc<ProcessControlBlock>>,
|
||||||
pub exit_code: i32,
|
pub exit_code: i32,
|
||||||
pub fd_table: Vec<Option<Arc<dyn File + Send + Sync>>>,
|
pub fd_table: Vec<Option<Arc<dyn File + Send + Sync>>>,
|
||||||
|
pub signals: SignalFlags,
|
||||||
pub tasks: Vec<Option<Arc<TaskControlBlock>>>,
|
pub tasks: Vec<Option<Arc<TaskControlBlock>>>,
|
||||||
pub task_res_allocator: RecycleAllocator,
|
pub task_res_allocator: RecycleAllocator,
|
||||||
pub mutex_list: Vec<Option<Arc<dyn Mutex>>>,
|
pub mutex_list: Vec<Option<Arc<dyn Mutex>>>,
|
||||||
@ -92,6 +94,7 @@ impl ProcessControlBlock {
|
|||||||
// 2 -> stderr
|
// 2 -> stderr
|
||||||
Some(Arc::new(Stdout)),
|
Some(Arc::new(Stdout)),
|
||||||
],
|
],
|
||||||
|
signals: SignalFlags::empty(),
|
||||||
tasks: Vec::new(),
|
tasks: Vec::new(),
|
||||||
task_res_allocator: RecycleAllocator::new(),
|
task_res_allocator: RecycleAllocator::new(),
|
||||||
mutex_list: Vec::new(),
|
mutex_list: Vec::new(),
|
||||||
@ -123,6 +126,7 @@ impl ProcessControlBlock {
|
|||||||
let mut process_inner = process.inner_exclusive_access();
|
let mut process_inner = process.inner_exclusive_access();
|
||||||
process_inner.tasks.push(Some(Arc::clone(&task)));
|
process_inner.tasks.push(Some(Arc::clone(&task)));
|
||||||
drop(process_inner);
|
drop(process_inner);
|
||||||
|
insert_into_pid2process(process.getpid(), Arc::clone(&process));
|
||||||
// add main thread to scheduler
|
// add main thread to scheduler
|
||||||
add_task(task);
|
add_task(task);
|
||||||
process
|
process
|
||||||
@ -209,6 +213,7 @@ impl ProcessControlBlock {
|
|||||||
children: Vec::new(),
|
children: Vec::new(),
|
||||||
exit_code: 0,
|
exit_code: 0,
|
||||||
fd_table: new_fd_table,
|
fd_table: new_fd_table,
|
||||||
|
signals: SignalFlags::empty(),
|
||||||
tasks: Vec::new(),
|
tasks: Vec::new(),
|
||||||
task_res_allocator: RecycleAllocator::new(),
|
task_res_allocator: RecycleAllocator::new(),
|
||||||
mutex_list: Vec::new(),
|
mutex_list: Vec::new(),
|
||||||
@ -242,6 +247,7 @@ impl ProcessControlBlock {
|
|||||||
let trap_cx = task_inner.get_trap_cx();
|
let trap_cx = task_inner.get_trap_cx();
|
||||||
trap_cx.kernel_sp = task.kstack.get_top();
|
trap_cx.kernel_sp = task.kstack.get_top();
|
||||||
drop(task_inner);
|
drop(task_inner);
|
||||||
|
insert_into_pid2process(child.getpid(), Arc::clone(&child));
|
||||||
// add this thread to scheduler
|
// add this thread to scheduler
|
||||||
add_task(task);
|
add_task(task);
|
||||||
child
|
child
|
||||||
|
29
os/src/task/signal.rs
Normal file
29
os/src/task/signal.rs
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
use bitflags::*;
|
||||||
|
|
||||||
|
bitflags! {
|
||||||
|
pub struct SignalFlags: u32 {
|
||||||
|
const SIGINT = 1 << 2;
|
||||||
|
const SIGILL = 1 << 4;
|
||||||
|
const SIGABRT = 1 << 6;
|
||||||
|
const SIGFPE = 1 << 8;
|
||||||
|
const SIGSEGV = 1 << 11;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SignalFlags {
|
||||||
|
pub fn check_error(&self) -> Option<(i32, &'static str)> {
|
||||||
|
if self.contains(Self::SIGINT) {
|
||||||
|
Some((-2, "Killed, SIGINT=2"))
|
||||||
|
} else if self.contains(Self::SIGILL) {
|
||||||
|
Some((-4, "Illegal Instruction, SIGILL=4"))
|
||||||
|
} else if self.contains(Self::SIGABRT) {
|
||||||
|
Some((-6, "Aborted, SIGABRT=6"))
|
||||||
|
} else if self.contains(Self::SIGFPE) {
|
||||||
|
Some((-8, "Erroneous Arithmetic Operation, SIGFPE=8"))
|
||||||
|
} else if self.contains(Self::SIGSEGV) {
|
||||||
|
Some((-11, "Segmentation Fault, SIGSEGV=11"))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -3,8 +3,8 @@ mod context;
|
|||||||
use crate::config::TRAMPOLINE;
|
use crate::config::TRAMPOLINE;
|
||||||
use crate::syscall::syscall;
|
use crate::syscall::syscall;
|
||||||
use crate::task::{
|
use crate::task::{
|
||||||
current_trap_cx, current_trap_cx_user_va, current_user_token, exit_current_and_run_next,
|
check_signals_of_current, current_add_signal, current_trap_cx, current_trap_cx_user_va,
|
||||||
suspend_current_and_run_next,
|
current_user_token, exit_current_and_run_next, suspend_current_and_run_next, SignalFlags,
|
||||||
};
|
};
|
||||||
use crate::timer::{check_timer, set_next_trigger};
|
use crate::timer::{check_timer, set_next_trigger};
|
||||||
use core::arch::{asm, global_asm};
|
use core::arch::{asm, global_asm};
|
||||||
@ -60,19 +60,18 @@ pub fn trap_handler() -> ! {
|
|||||||
| Trap::Exception(Exception::InstructionPageFault)
|
| Trap::Exception(Exception::InstructionPageFault)
|
||||||
| Trap::Exception(Exception::LoadFault)
|
| Trap::Exception(Exception::LoadFault)
|
||||||
| Trap::Exception(Exception::LoadPageFault) => {
|
| Trap::Exception(Exception::LoadPageFault) => {
|
||||||
|
/*
|
||||||
println!(
|
println!(
|
||||||
"[kernel] {:?} in application, bad addr = {:#x}, bad instruction = {:#x}, kernel killed it.",
|
"[kernel] {:?} in application, bad addr = {:#x}, bad instruction = {:#x}, kernel killed it.",
|
||||||
scause.cause(),
|
scause.cause(),
|
||||||
stval,
|
stval,
|
||||||
current_trap_cx().sepc,
|
current_trap_cx().sepc,
|
||||||
);
|
);
|
||||||
// page fault exit code
|
*/
|
||||||
exit_current_and_run_next(-2);
|
current_add_signal(SignalFlags::SIGSEGV);
|
||||||
}
|
}
|
||||||
Trap::Exception(Exception::IllegalInstruction) => {
|
Trap::Exception(Exception::IllegalInstruction) => {
|
||||||
println!("[kernel] IllegalInstruction in application, kernel killed it.");
|
current_add_signal(SignalFlags::SIGILL);
|
||||||
// illegal instruction exit code
|
|
||||||
exit_current_and_run_next(-3);
|
|
||||||
}
|
}
|
||||||
Trap::Interrupt(Interrupt::SupervisorTimer) => {
|
Trap::Interrupt(Interrupt::SupervisorTimer) => {
|
||||||
set_next_trigger();
|
set_next_trigger();
|
||||||
@ -87,6 +86,11 @@ pub fn trap_handler() -> ! {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// check signals
|
||||||
|
if let Some((errno, msg)) = check_signals_of_current() {
|
||||||
|
println!("[kernel] {}", msg);
|
||||||
|
exit_current_and_run_next(errno);
|
||||||
|
}
|
||||||
trap_return();
|
trap_return();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,3 +9,4 @@ edition = "2018"
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
buddy_system_allocator = "0.6"
|
buddy_system_allocator = "0.6"
|
||||||
bitflags = "1.2.1"
|
bitflags = "1.2.1"
|
||||||
|
riscv = { git = "https://github.com/rcore-os/riscv", features = ["inline-asm"] }
|
||||||
|
@ -15,7 +15,7 @@ pub fn main(argc: usize, argv: &[&str]) -> i32 {
|
|||||||
panic!("Error occured when opening file");
|
panic!("Error occured when opening file");
|
||||||
}
|
}
|
||||||
let fd = fd as usize;
|
let fd = fd as usize;
|
||||||
let mut buf = [0u8; 16];
|
let mut buf = [0u8; 256];
|
||||||
loop {
|
loop {
|
||||||
let size = read(fd, &mut buf) as usize;
|
let size = read(fd, &mut buf) as usize;
|
||||||
if size == 0 {
|
if size == 0 {
|
||||||
|
10
user/src/bin/infloop.rs
Normal file
10
user/src/bin/infloop.rs
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
#![no_std]
|
||||||
|
#![no_main]
|
||||||
|
#![allow(clippy::empty_loop)]
|
||||||
|
|
||||||
|
extern crate user_lib;
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub fn main(_argc: usize, _argv: &[&str]) -> ! {
|
||||||
|
loop {}
|
||||||
|
}
|
17
user/src/bin/priv_csr.rs
Normal file
17
user/src/bin/priv_csr.rs
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
#![no_std]
|
||||||
|
#![no_main]
|
||||||
|
|
||||||
|
#[macro_use]
|
||||||
|
extern crate user_lib;
|
||||||
|
|
||||||
|
use riscv::register::sstatus::{self, SPP};
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
fn main() -> i32 {
|
||||||
|
println!("Try to access privileged CSR in U Mode");
|
||||||
|
println!("Kernel should kill this application!");
|
||||||
|
unsafe {
|
||||||
|
sstatus::set_spp(SPP::User);
|
||||||
|
}
|
||||||
|
0
|
||||||
|
}
|
17
user/src/bin/priv_inst.rs
Normal file
17
user/src/bin/priv_inst.rs
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
#![no_std]
|
||||||
|
#![no_main]
|
||||||
|
|
||||||
|
#[macro_use]
|
||||||
|
extern crate user_lib;
|
||||||
|
|
||||||
|
use core::arch::asm;
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
fn main() -> i32 {
|
||||||
|
println!("Try to execute privileged instruction in U Mode");
|
||||||
|
println!("Kernel should kill this application!");
|
||||||
|
unsafe {
|
||||||
|
asm!("sret");
|
||||||
|
}
|
||||||
|
0
|
||||||
|
}
|
15
user/src/bin/store_fault.rs
Normal file
15
user/src/bin/store_fault.rs
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
#![no_std]
|
||||||
|
#![no_main]
|
||||||
|
|
||||||
|
#[macro_use]
|
||||||
|
extern crate user_lib;
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
fn main() -> i32 {
|
||||||
|
println!("Into Test store_fault, we will insert an invalid store operation...");
|
||||||
|
println!("Kernel should kill this application!");
|
||||||
|
unsafe {
|
||||||
|
core::ptr::null_mut::<u8>().write_volatile(0);
|
||||||
|
}
|
||||||
|
0
|
||||||
|
}
|
46
user/src/bin/until_timeout.rs
Normal file
46
user/src/bin/until_timeout.rs
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
#![no_std]
|
||||||
|
#![no_main]
|
||||||
|
|
||||||
|
#[macro_use]
|
||||||
|
extern crate user_lib;
|
||||||
|
|
||||||
|
use user_lib::{exec, fork, get_time, kill, waitpid, waitpid_nb, SignalFlags};
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub fn main(argc: usize, argv: &[&str]) -> i32 {
|
||||||
|
assert_eq!(argc, 3, "argc must be 3!");
|
||||||
|
let timeout_ms = argv[2]
|
||||||
|
.parse::<isize>()
|
||||||
|
.expect("Error when parsing timeout!");
|
||||||
|
let pid = fork() as usize;
|
||||||
|
if pid == 0 {
|
||||||
|
if exec(argv[1], &[core::ptr::null::<u8>()]) != 0 {
|
||||||
|
println!("Error when executing '{}'", argv[1]);
|
||||||
|
return -4;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
let start_time = get_time();
|
||||||
|
let mut child_exited = false;
|
||||||
|
let mut exit_code: i32 = 0;
|
||||||
|
loop {
|
||||||
|
if get_time() - start_time > timeout_ms {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if waitpid_nb(pid, &mut exit_code) as usize == pid {
|
||||||
|
child_exited = true;
|
||||||
|
println!(
|
||||||
|
"child exited in {}ms, exit_code = {}",
|
||||||
|
get_time() - start_time,
|
||||||
|
exit_code,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !child_exited {
|
||||||
|
println!("child has run for {}ms, kill it!", timeout_ms);
|
||||||
|
kill(pid, SignalFlags::SIGINT.bits());
|
||||||
|
assert_eq!(waitpid(pid, &mut exit_code) as usize, pid);
|
||||||
|
println!("exit code of the child is {}", exit_code);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
0
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
use super::exit;
|
use super::{getpid, kill, SignalFlags};
|
||||||
|
|
||||||
#[panic_handler]
|
#[panic_handler]
|
||||||
fn panic_handler(panic_info: &core::panic::PanicInfo) -> ! {
|
fn panic_handler(panic_info: &core::panic::PanicInfo) -> ! {
|
||||||
@ -13,5 +13,6 @@ fn panic_handler(panic_info: &core::panic::PanicInfo) -> ! {
|
|||||||
} else {
|
} else {
|
||||||
println!("Panicked: {}", err);
|
println!("Panicked: {}", err);
|
||||||
}
|
}
|
||||||
exit(-1);
|
kill(getpid() as usize, SignalFlags::SIGABRT.bits());
|
||||||
|
unreachable!()
|
||||||
}
|
}
|
||||||
|
@ -127,6 +127,25 @@ pub fn waitpid(pid: usize, exit_code: &mut i32) -> isize {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn waitpid_nb(pid: usize, exit_code: &mut i32) -> isize {
|
||||||
|
sys_waitpid(pid as isize, exit_code as *mut _)
|
||||||
|
}
|
||||||
|
|
||||||
|
bitflags! {
|
||||||
|
pub struct SignalFlags: i32 {
|
||||||
|
const SIGINT = 1 << 2;
|
||||||
|
const SIGILL = 1 << 4;
|
||||||
|
const SIGABRT = 1 << 6;
|
||||||
|
const SIGFPE = 1 << 8;
|
||||||
|
const SIGSEGV = 1 << 11;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn kill(pid: usize, signal: i32) -> isize {
|
||||||
|
sys_kill(pid, signal)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn sleep(sleep_ms: usize) {
|
pub fn sleep(sleep_ms: usize) {
|
||||||
sys_sleep(sleep_ms);
|
sys_sleep(sleep_ms);
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,7 @@ const SYSCALL_WRITE: usize = 64;
|
|||||||
const SYSCALL_EXIT: usize = 93;
|
const SYSCALL_EXIT: usize = 93;
|
||||||
const SYSCALL_SLEEP: usize = 101;
|
const SYSCALL_SLEEP: usize = 101;
|
||||||
const SYSCALL_YIELD: usize = 124;
|
const SYSCALL_YIELD: usize = 124;
|
||||||
|
const SYSCALL_KILL: usize = 129;
|
||||||
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;
|
||||||
@ -81,6 +82,10 @@ pub fn sys_yield() -> isize {
|
|||||||
syscall(SYSCALL_YIELD, [0, 0, 0])
|
syscall(SYSCALL_YIELD, [0, 0, 0])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn sys_kill(pid: usize, signal: i32) -> isize {
|
||||||
|
syscall(SYSCALL_KILL, [pid, signal as usize, 0])
|
||||||
|
}
|
||||||
|
|
||||||
pub fn sys_get_time() -> isize {
|
pub fn sys_get_time() -> isize {
|
||||||
syscall(SYSCALL_GET_TIME, [0, 0, 0])
|
syscall(SYSCALL_GET_TIME, [0, 0, 0])
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user