From 03ee0e55ca06f03b3b727b04930eeed118c6ef79 Mon Sep 17 00:00:00 2001 From: X512 Date: Mon, 16 Nov 2020 21:11:23 +0900 Subject: [PATCH] kernel/team: add ability to get parent PID of arbitrary process MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes #16607. Change-Id: Ia20bbde2cf078b6b99904f4e868730cbc70889c5 Reviewed-on: https://review.haiku-os.org/c/haiku/+/3400 Reviewed-by: X512 Reviewed-by: Axel Dörfler Reviewed-by: Adrien Destugues --- src/system/kernel/team.cpp | 59 ++++++++++++++++++++++++++++++-------- 1 file changed, 47 insertions(+), 12 deletions(-) diff --git a/src/system/kernel/team.cpp b/src/system/kernel/team.cpp index f3e85edc1d..51421eb595 100644 --- a/src/system/kernel/team.cpp +++ b/src/system/kernel/team.cpp @@ -1223,6 +1223,50 @@ dump_teams(int argc, char** argv) // #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. The caller must hold the lock of both \a parent and \a team. @@ -3857,13 +3901,9 @@ getpid(void) pid_t -getppid(void) +getppid() { - Team* team = thread_get_current_thread()->team; - - TeamLocker teamLocker(team); - - return team->parent->id; + return _getppid(0); } @@ -3998,11 +4038,6 @@ _user_wait_for_child(thread_id child, uint32 flags, siginfo_t* userInfo, pid_t _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; switch (which) { case SESSION_ID: @@ -4012,7 +4047,7 @@ _user_process_info(pid_t process, int32 which) result = getpgid(process); break; case PARENT_ID: - result = getppid(); + result = _getppid(process); break; default: return B_BAD_VALUE;