diff --git a/apps/sh.c b/apps/sh.c index bd36b068..d92c6070 100644 --- a/apps/sh.c +++ b/apps/sh.c @@ -1882,7 +1882,7 @@ uint32_t shell_cmd_fg(int argc, char * argv[]) { return 0; } - if (kill(pid, SIGCONT) < 0) { + if (kill(-pid, SIGCONT) < 0) { fprintf(stderr, "no current job / bad pid\n"); hashmap_remove(job_hash, (void*)pid); return 1; diff --git a/base/usr/include/kernel/system.h b/base/usr/include/kernel/system.h index cd583187..fa1e41e8 100644 --- a/base/usr/include/kernel/system.h +++ b/base/usr/include/kernel/system.h @@ -224,6 +224,7 @@ typedef struct { extern void handle_signal(process_t *, signal_t *); extern int send_signal(pid_t process, uint32_t signal, int force); +extern int group_send_signal(int group, uint32_t signal, int force_root); #define USER_STACK_BOTTOM 0xAFF00000 #define USER_STACK_TOP 0xB0000000 diff --git a/kernel/fs/tty.c b/kernel/fs/tty.c index 40802ff2..6b81e1f5 100644 --- a/kernel/fs/tty.c +++ b/kernel/fs/tty.c @@ -139,7 +139,7 @@ void tty_input_process(pty_t * pty, uint8_t c) { } clear_input_buffer(pty); if (pty->fg_proc) { - send_signal(pty->fg_proc, sig, 1); + group_send_signal(pty->fg_proc, sig, 1); } return; } diff --git a/kernel/sys/signal.c b/kernel/sys/signal.c index a347393e..261f3370 100644 --- a/kernel/sys/signal.c +++ b/kernel/sys/signal.c @@ -267,3 +267,35 @@ int send_signal(pid_t process, uint32_t signal, int force_root) { return 0; } +int group_send_signal(int group, uint32_t signal, int force_root) { + + int kill_self = 0; + int killed_something = 0; + + debug_print(WARNING, "killing group %d", group); + + foreach(node, process_list) { + process_t * proc = node->value; + debug_print(WARNING, "examining %d %d %d", proc->id, proc->job, proc->group); + if (proc->group == proc->id && proc->job == group) { + /* Only thread group leaders */ + debug_print(WARNING, "killing %d", proc->group); + if (proc->group == current_process->group) { + kill_self = 1; + } else { + if (send_signal(proc->group, signal, force_root) == 0) { + killed_something = 1; + } + } + } + } + + if (kill_self) { + if (send_signal(current_process->group, signal, force_root) == 0) { + killed_something = 1; + } + } + + return !!killed_something; +} + diff --git a/kernel/sys/syscall.c b/kernel/sys/syscall.c index 1e394914..d6230bd9 100644 --- a/kernel/sys/syscall.c +++ b/kernel/sys/syscall.c @@ -780,7 +780,11 @@ static int sys_shm_release(char * path) { } static int sys_kill(pid_t process, uint32_t signal) { - return send_signal(process, signal, 0); + if (process < -1) { + return group_send_signal(-process, signal, 0); + } else { + return send_signal(process, signal, 0); + } } static int sys_gettimeofday(struct timeval * tv, void * tz) {