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:
parent
05565bad58
commit
d8f0dd6f3b
8 changed files with 157 additions and 2 deletions
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue