1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-04 20:57:35 +00:00

Start working on sessions and process groups.

This commit is contained in:
Andreas Kling 2018-11-02 12:56:51 +01:00
parent 05565bad58
commit d8f0dd6f3b
8 changed files with 157 additions and 2 deletions

View file

@ -129,6 +129,16 @@ void Process::allocateLDT()
m_tss.ldt = m_ldt_selector;
}
template<typename Callback>
static void forEachProcess(Callback callback)
{
ASSERT_INTERRUPTS_DISABLED();
for (auto* process = s_processes->head(); process; process = process->next()) {
if (!callback(*process))
break;
}
}
Vector<Process*> Process::allProcesses()
{
InterruptDisabler disabler;
@ -406,6 +416,16 @@ Process::Process(String&& name, uid_t uid, gid_t gid, pid_t parentPID, RingLevel
, m_tty(tty)
, m_parentPID(parentPID)
{
{
// FIXME: Use a ProcessHandle? Presumably we're executing *IN* the parent right now though..
InterruptDisabler disabler;
if (auto* parent = Process::fromPID(m_parentPID)) {
m_sid = parent->m_sid;
m_pgid = parent->m_pgid;
}
}
m_page_directory = (PageDirectory*)kmalloc_page_aligned(sizeof(PageDirectory));
MM.populate_page_directory(*this);
@ -1152,3 +1172,80 @@ bool Process::validate_user_write(LinearAddress laddr) const
InterruptDisabler disabler;
return MM.validate_user_write(*this, laddr);
}
pid_t Process::sys$getsid(pid_t pid)
{
if (pid == 0)
return m_sid;
InterruptDisabler disabler;
auto* process = Process::fromPID(pid);
if (!process)
return -ESRCH;
if (m_sid != process->m_sid)
return -EPERM;
return process->m_sid;
}
pid_t Process::sys$setsid()
{
InterruptDisabler disabler;
bool found_process_with_same_pgid_as_my_pid = false;
forEachProcess([&] (auto& process) {
if (process.pgid() == pid()) {
found_process_with_same_pgid_as_my_pid = true;
return false;
}
return true;
});
if (found_process_with_same_pgid_as_my_pid)
return -EPERM;
m_sid = m_pid;
m_pgid = m_pid;
return m_sid;
}
pid_t Process::sys$getpgid(pid_t pid)
{
if (pid == 0)
return m_pgid;
InterruptDisabler disabler; // FIXME: Use a ProcessHandle
auto* process = Process::fromPID(pid);
if (!process)
return -ESRCH;
return process->m_pgid;
}
pid_t Process::sys$getpgrp()
{
return m_pgid;
}
static pid_t get_sid_from_pgid(pid_t pgid)
{
InterruptDisabler disabler;
auto* group_leader = Process::fromPID(pgid);
if (!group_leader)
return -1;
return group_leader->sid();
}
int Process::sys$setpgid(pid_t specified_pid, pid_t specified_pgid)
{
InterruptDisabler disabler; // FIXME: Use a ProcessHandle
pid_t pid = specified_pid ? specified_pid : m_pid;
if (specified_pgid < 0)
return -EINVAL;
auto* process = Process::fromPID(pid);
if (!process)
return -ESRCH;
pid_t new_pgid = specified_pgid ? specified_pgid : process->m_pid;
pid_t current_sid = get_sid_from_pgid(process->m_pgid);
pid_t new_sid = get_sid_from_pgid(new_pgid);
if (current_sid != new_sid) {
// Can't move a process between sessions.
return -EPERM;
}
// FIXME: There are more EPERM conditions to check for here..
process->m_pgid = new_pgid;
return 0;
}