mirror of
https://github.com/ish-app/ish.git
synced 2026-01-25 14:06:40 +00:00
70 lines
1.7 KiB
C
70 lines
1.7 KiB
C
#include "util/list.h"
|
|
#include "kernel/calls.h"
|
|
#include "kernel/task.h"
|
|
|
|
dword_t sys_setpgid(dword_t id, dword_t pgid) {
|
|
STRACE("setpgid(%d, %d)", id, pgid);
|
|
int err;
|
|
if (id == 0)
|
|
id = current->pid;
|
|
if (pgid == 0)
|
|
pgid = id;
|
|
lock(&pids_lock);
|
|
struct pid *pid = pid_get(id);
|
|
|
|
// when creating a process group, you need to specify your own pid
|
|
// TODO or a child in the same session
|
|
err = _EPERM;
|
|
if (list_empty(&pid->pgroup) && id != pgid)
|
|
goto out;
|
|
// TODO you can only join a process group in the same session
|
|
|
|
struct task *task = pid->task;
|
|
err = _ESRCH;
|
|
if (task == NULL)
|
|
goto out;
|
|
|
|
// you can only change the process group of yourself or a child
|
|
err = _ESRCH;
|
|
if (task != current && task->parent != current)
|
|
goto out;
|
|
// a session leader cannot create a process group
|
|
err = _EPERM;
|
|
if (task->sid == task->pid)
|
|
goto out;
|
|
|
|
// TODO cannot set process group of a child that has done exec
|
|
|
|
if (task->pgid != pgid) {
|
|
list_remove(&task->pgroup);
|
|
task->pgid = pgid;
|
|
list_add(&pid->pgroup, &task->pgroup);
|
|
}
|
|
|
|
err = 0;
|
|
out:
|
|
unlock(&pids_lock);
|
|
return err;
|
|
}
|
|
|
|
dword_t sys_setpgrp() {
|
|
return sys_setpgid(0, 0);
|
|
}
|
|
|
|
dword_t sys_setsid() {
|
|
lock(&pids_lock);
|
|
if (current->pgid == current->pid || current->sid == current->pid) {
|
|
unlock(&pids_lock);
|
|
return _EPERM;
|
|
}
|
|
|
|
struct pid *pid = pid_get(current->pid);
|
|
list_add(&pid->session, ¤t->session);
|
|
current->sid = current->pid;
|
|
list_add(&pid->pgroup, ¤t->pgroup);
|
|
current->pgid = current->pid;
|
|
|
|
unlock(&pids_lock);
|
|
return 0;
|
|
}
|