diff --git a/kernel-src/include/kernel/scheduler.h b/kernel-src/include/kernel/scheduler.h index 05eda5f7..3ac4d6e2 100644 --- a/kernel-src/include/kernel/scheduler.h +++ b/kernel-src/include/kernel/scheduler.h @@ -166,5 +166,6 @@ void sched_sleepus(size_t us); void sched_apentry(); void sched_inactiveproc(proc_t *proc); void sched_terminateprogram(int status); +int sched_signalall(int signal, proc_t *sender); #endif diff --git a/kernel-src/sys/scheduler.c b/kernel-src/sys/scheduler.c index 4240ce09..19cfcf54 100644 --- a/kernel-src/sys/scheduler.c +++ b/kernel-src/sys/scheduler.c @@ -12,6 +12,7 @@ #include #include #include +#include #define QUANTUM_US 100000 #define SCHEDULER_STACK_SIZE PAGE_SIZE * 16 @@ -49,6 +50,30 @@ proc_t *sched_getprocfrompid(int pid) { return proc; } +int sched_signalall(int signal, proc_t *sender) { + MUTEX_ACQUIRE(&sched_pidtablemutex, false); + + pid_t senderpgid = sender ? jobctl_getpgid(sender) : 0; + + size_t donecount = 0; + HASHTABLE_FOREACH(&pidtable) { + proc_t *current = entry->value; + // init does not get signaled + if (current->pid == 1) + continue; + + pid_t currentpgid = jobctl_getpgid(current); + + if (senderpgid == 0 || (signal == SIGCONT && currentpgid == senderpgid) || auth_process_check(&sender->cred, AUTH_ACTIONS_PROCESS_SIGNAL, current)) { + ++donecount; + signal_signalproc(current, signal); + } + } + + MUTEX_RELEASE(&sched_pidtablemutex); + return donecount == 0 ? EPERM : 0; +} + static void rtdpc(context_t *, dpcarg_t arg) { signal_signalproc(arg, SIGALRM); } diff --git a/kernel-src/sys/syscalls/kill.c b/kernel-src/sys/syscalls/kill.c index 0b413a62..c722895d 100644 --- a/kernel-src/sys/syscalls/kill.c +++ b/kernel-src/sys/syscalls/kill.c @@ -19,14 +19,9 @@ syscallret_t syscall_kill(context_t *context, int pid, int signal) { effectivepid = -1; else if (pid < -1) effectivepid = -pid; // target specific process group - - if (effectivepid == -1) { - ret.errno = ESRCH; - return ret; - } proc_t *target = sched_getprocfrompid(effectivepid); - if (target == NULL && pid != 0) { + if (target == NULL && pid != 0 && pid != -1) { ret.errno = ESRCH; return ret; } @@ -43,6 +38,8 @@ syscallret_t syscall_kill(context_t *context, int pid, int signal) { } signal_signalproc(target, signal); + } else if (pid == -1) { + ret.errno = sched_signalall(signal, _cpu()->thread->proc); } else { ret.errno = jobctl_signal(target, signal, _cpu()->thread->proc); }