diff --git a/kernel/src/syscall/mod.rs b/kernel/src/syscall/mod.rs index 3504429..05406ab 100644 --- a/kernel/src/syscall/mod.rs +++ b/kernel/src/syscall/mod.rs @@ -82,7 +82,7 @@ pub fn syscall(id: usize, args: [usize; 6], tf: &mut TrapFrame) -> isize { 059 => sys_exec(args[0] as *const u8, args[1] as *const *const u8, args[2] as *const *const u8, tf), 060 => sys_exit(args[0] as usize), 061 => sys_wait4(args[0] as isize, args[1] as *mut i32), // TODO: wait4 - 062 => sys_kill(args[0]), + 062 => sys_kill(args[0], args[1]), 063 => sys_uname(args[0] as *mut u8), // 072 => sys_fcntl(), 074 => sys_fsync(args[0]), diff --git a/kernel/src/syscall/proc.rs b/kernel/src/syscall/proc.rs index 851f8fd..c5a1f9c 100644 --- a/kernel/src/syscall/proc.rs +++ b/kernel/src/syscall/proc.rs @@ -146,13 +146,35 @@ pub fn sys_yield() -> SysResult { } /// Kill the process -pub fn sys_kill(pid: usize) -> SysResult { - info!("{} killed: {}", thread::current().id(), pid); - processor().manager().exit(pid, 0x100); - if pid == thread::current().id() { - processor().yield_now(); +pub fn sys_kill(pid: usize, sig: usize) -> SysResult { + info!("kill: {} killed: {} with sig {}", thread::current().id(), pid, sig); + let current_pid = process().pid.get().clone(); + if current_pid == pid { + // killing myself + sys_exit_group(sig); + Ok(0) + } else { + if let Some(proc_arc) = PROCESSES.read().get(&pid).and_then(|weak| weak.upgrade()) { + let proc = proc_arc.lock(); + // quit all threads + for tid in proc.threads.iter() { + processor().manager().exit(*tid, sig); + } + // notify parent and fill exit code + // avoid deadlock + let proc_parent = proc.parent.clone(); + let pid = proc.pid.get(); + drop(proc); + if let Some(parent) = proc_parent { + let mut parent = parent.lock(); + parent.child_exit_code.insert(pid, sig); + parent.child_exit.notify_one(); + } + Ok(0) + } else { + Err(SysError::EINVAL) + } } - Ok(0) } /// Get the current process id diff --git a/tests/fork.exp b/tests/fork.exp index a105ea7..49d9c1e 100644 --- a/tests/fork.exp +++ b/tests/fork.exp @@ -5,8 +5,8 @@ sleep 2 expect ">>" sleep 2 send -- "biscuit/fork\r" -sleep 2 +sleep 5 expect "hello from 100" expect "parent done!" send -- "^Ax" -wait -nowait +wait diff --git a/tests/killtest.exp b/tests/killtest.exp new file mode 100644 index 0000000..22c84b6 --- /dev/null +++ b/tests/killtest.exp @@ -0,0 +1,11 @@ +set timeout -1 +cd ../kernel +spawn make run arch=x86_64 +sleep 2 +expect ">>" +sleep 2 +send -- "biscuit/killtest\r" +sleep 2 +expect "success" +send -- "^Ax" +wait diff --git a/user b/user index 091b95f..095cfa8 160000 --- a/user +++ b/user @@ -1 +1 @@ -Subproject commit 091b95fae21bf42c8ee403056bda830f65255286 +Subproject commit 095cfa8e66792544e491945eec18daad3e6d58b3