kernel/team: add ability to get parent PID of arbitrary process

Fixes #16607.

Change-Id: Ia20bbde2cf078b6b99904f4e868730cbc70889c5
Reviewed-on: https://review.haiku-os.org/c/haiku/+/3400
Reviewed-by: X512 <[email protected]>
Reviewed-by: Axel Dörfler <[email protected]>
Reviewed-by: Adrien Destugues <[email protected]>
This commit is contained in:
X512
2020-12-16 12:23:25 +00:00
committed by Adrien Destugues
parent 10074df18f
commit 03ee0e55ca
+47 -12
View File
@@ -1223,6 +1223,50 @@ dump_teams(int argc, char** argv)
// #pragma mark - Private functions // #pragma mark - Private functions
/*! Get the parent of a given process.
Used in the implementation of getppid (where a process can get its own
parent, only) as well as in user_process_info where the information is
available to anyone (allowing to display a tree of running processes)
*/
static pid_t
_getppid(pid_t id)
{
if (id < 0) {
errno = EINVAL;
return -1;
}
if (id == 0) {
Team* team = thread_get_current_thread()->team;
TeamLocker teamLocker(team);
if (team->parent == NULL) {
errno = EINVAL;
return -1;
}
return team->parent->id;
}
Team* team = Team::GetAndLock(id);
if (team == NULL) {
errno = ESRCH;
return -1;
}
pid_t parentID;
if (team->parent == NULL) {
errno = EINVAL;
parentID = -1;
} else
parentID = team->parent->id;
team->UnlockAndReleaseReference();
return parentID;
}
/*! Inserts team \a team into the child list of team \a parent. /*! Inserts team \a team into the child list of team \a parent.
The caller must hold the lock of both \a parent and \a team. The caller must hold the lock of both \a parent and \a team.
@@ -3857,13 +3901,9 @@ getpid(void)
pid_t pid_t
getppid(void) getppid()
{ {
Team* team = thread_get_current_thread()->team; return _getppid(0);
TeamLocker teamLocker(team);
return team->parent->id;
} }
@@ -3998,11 +4038,6 @@ _user_wait_for_child(thread_id child, uint32 flags, siginfo_t* userInfo,
pid_t pid_t
_user_process_info(pid_t process, int32 which) _user_process_info(pid_t process, int32 which)
{ {
// we only allow to return the parent of the current process
if (which == PARENT_ID
&& process != 0 && process != thread_get_current_thread()->team->id)
return B_BAD_VALUE;
pid_t result; pid_t result;
switch (which) { switch (which) {
case SESSION_ID: case SESSION_ID:
@@ -4012,7 +4047,7 @@ _user_process_info(pid_t process, int32 which)
result = getpgid(process); result = getpgid(process);
break; break;
case PARENT_ID: case PARENT_ID:
result = getppid(); result = _getppid(process);
break; break;
default: default:
return B_BAD_VALUE; return B_BAD_VALUE;