2#include "pedigree/kernel/syscallError.h"
3#include "pedigree/kernel/utilities/Pointers.h"
4#include "pedigree/kernel/utilities/assert.h"
6#include "PosixProcess.h"
7#include "TerminalControl.h"
9ProcessGroup::~ProcessGroup() {
11 assert(!firstMember && !memberCount);
13 ProcessGroupManager::instance().unregisterGroup(processGroupId,
this);
16void PosixProcess::initializeJobControl(
Process* parent) {
18 if (parent && parent->getType() == Posix) {
22 setCttyContext(parent->acquireCttyContext());
28 group->processGroupId =
getUserspaceId(Process::rootPidNamespace().get());
29 group->sessionId =
getUserspaceId(Process::rootPidNamespace().get());
31 group->identity = pidIdentity();
32 group->sessionIdentity = pidIdentity();
33 setProcessGroup(group);
43 m_GroupPrevious->m_GroupNext = m_GroupNext;
45 old->firstMember = m_GroupNext;
47 m_GroupNext->m_GroupPrevious = m_GroupPrevious;
49 if (old->Leader ==
this)
50 old->Leader =
nullptr;
52 m_pProcessGroup = group;
53 m_GroupPrevious = m_GroupNext =
nullptr;
56 if (!group->sessionId)
57 group->sessionId = m_SessionId;
58 m_SessionId = group->sessionId;
59 m_GroupNext = group->firstMember;
61 m_GroupNext->m_GroupPrevious =
this;
62 group->firstMember =
this;
64 m_GroupMembership =
static_cast<size_t>(group->processGroupId) ==
68 if (!group->registered)
69 ProcessGroupManager::instance().
registerGroup(group->processGroupId, group);
71 if (old && !old->memberCount)
75void PosixProcess::inheritProcessGroup(
PosixProcess* parent) {
79 setProcessGroup(parent->m_pProcessGroup);
83 return m_pProcessGroup;
90 id = space ? m_pProcessGroup->identity->id(space) : m_pProcessGroup->processGroupId;
94void PosixProcess::leaveProcessGroup() {
95 setProcessGroup(
nullptr);
98void PosixProcess::setGroupMembership(Membership type) {
100 assert(type == m_GroupMembership);
105 return m_GroupMembership;
110 return space && m_pProcessGroup ? m_pProcessGroup->sessionIdentity->id(space) : m_SessionId;
113bool PosixProcess::sharesSession(
const PosixProcess& other)
const {
115 return m_SessionId && m_SessionId == other.m_SessionId;
118bool PosixProcess::jobControlReady()
const {
120 return m_SessionId && m_pProcessGroup;
123void PosixProcess::markExecCommitted() {
125 m_ExecCommitted =
true;
128bool PosixProcess::hasExecCommitted()
const {
130 return m_ExecCommitted;
133int PosixProcess::createSession() {
137 ERROR(
"PosixProcess::createSession - out of memory!");
138 SYSCALL_ERROR(OutOfMemory);
144 if (ProcessGroupManager::instance().findGroup(
146 error = Error::NotEnoughPermissions;
148 prepared.get()->processGroupId =
getUserspaceId(Process::rootPidNamespace().get());
149 prepared.get()->sessionId =
getUserspaceId(Process::rootPidNamespace().get());
150 prepared.get()->Leader =
this;
151 prepared.get()->identity = pidIdentity();
152 prepared.get()->sessionIdentity = pidIdentity();
153 setProcessGroup(prepared.releaseOwnership());
162int PosixProcess::changeProcessGroup(
PosixProcess& caller,
int id) {
165 auto* visible = ProcessGroupManager::instance().
findGroup(
id, caller.pidNamespace().
get());
167 id = visible->processGroupId;
168 }
else if (
static_cast<size_t>(
id) ==
getUserspaceId(caller.pidNamespace().
get())) {
171 syscallError(Error::NotEnoughPermissions);
178 if (
static_cast<size_t>(
id) ==
getUserspaceId(Process::rootPidNamespace().get())) {
185 if (
this != &caller &&
getParent() != &caller)
186 error = Error::NoSuchProcess;
187 else if (m_SessionId != caller.m_SessionId)
188 error = Error::NotEnoughPermissions;
189 else if (
this != &caller && m_ExecCommitted)
190 error = Error::PermissionDenied;
191 else if (m_SessionId ==
getUserspaceId(Process::rootPidNamespace().get())) {
192 error = Error::NotEnoughPermissions;
193 }
else if (existing && existing->sessionId != m_SessionId) {
194 error = Error::NotEnoughPermissions;
196 setProcessGroup(existing);
197 else if (
static_cast<size_t>(
id) !=
getUserspaceId(Process::rootPidNamespace().get())) {
198 error = Error::NotEnoughPermissions;
199 }
else if (!prepared) {
200 error = Error::OutOfMemory;
202 prepared.get()->processGroupId = id;
203 prepared.get()->sessionId = m_SessionId;
204 prepared.get()->Leader =
this;
205 prepared.get()->identity = pidIdentity();
206 prepared.get()->sessionIdentity = m_pProcessGroup->sessionIdentity;
211 return error ? -1 : 0;
void registerGroup(size_t gid, ProcessGroup *group)
ProcessGroup * findGroup(size_t gid) const
size_t getUserspaceId() const
T * releaseOwnership() noexcept