From ff13369073da3ab022a454f61b4b394568c69b18 Mon Sep 17 00:00:00 2001 From: Matheus Date: Wed, 22 May 2024 09:46:31 -0300 Subject: [PATCH] setpgid: support changing between process groups and doing it for other processes --- kernel-src/sys/syscalls/setpid.c | 43 +++++++++++++++++++++++++++++--- 1 file changed, 39 insertions(+), 4 deletions(-) diff --git a/kernel-src/sys/syscalls/setpid.c b/kernel-src/sys/syscalls/setpid.c index a143a0a2..86cd5844 100644 --- a/kernel-src/sys/syscalls/setpid.c +++ b/kernel-src/sys/syscalls/setpid.c @@ -12,10 +12,45 @@ syscallret_t syscall_setsid(context_t *) { syscallret_t syscall_setpgid(context_t *, pid_t pid, pid_t pgid) { syscallret_t ret; - __assert(pid == 0 || pid == _cpu()->thread->proc->pid); - __assert(pgid == 0 || pgid == _cpu()->thread->proc->pid); - ret.errno = jobctl_newgroup(_cpu()->thread->proc); - ret.ret = ret.errno ? -1 : _cpu()->thread->proc->pid; + proc_t *proc = NULL; + if (pid == 0) { + proc = _cpu()->thread->proc; + PROC_HOLD(proc); + } else { + proc = sched_getprocfrompid(pid); + } + + if (proc == NULL) { + ret.errno = ESRCH; + return ret; + } + + proc_t *pgrp = NULL; + if (pgid == 0) { + pgrp = _cpu()->thread->proc; + PROC_HOLD(pgrp); + } else { + pgrp = sched_getprocfrompid(pgid); + } + + if (pgrp == NULL) { + PROC_RELEASE(proc); + ret.errno = EPERM; + return ret; + } + + if (pgid == pid || pgid == 0) { + // create new group for process + ret.errno = jobctl_newgroup(proc); + } else { + // switch process group + ret.errno = jobctl_changegroup(proc, pgrp); + } + + PROC_RELEASE(pgrp); + PROC_RELEASE(proc); + + ret.ret = ret.errno ? -1 : 0; return ret; }