From 1bf05d0972b043ef4e65c812bcbc4c11b2d6cbdb Mon Sep 17 00:00:00 2001
From: Narvin Singh <Narvin.A.Singh@gmail.com>
Date: Mon, 25 Oct 2021 22:29:52 -0400
Subject: [PATCH] Feat: Return a PID in edge cases

- Return the first ancestor PID if root_name is not found.
- Return the process' own PID if its own name is root_name.
---
 rpid | 28 ++++++++++++++++++++++------
 1 file changed, 22 insertions(+), 6 deletions(-)

diff --git a/rpid b/rpid
index b1f2b71..c957f84 100755
--- a/rpid
+++ b/rpid
@@ -21,6 +21,16 @@ EXAMPLES:
         process.
 
                 rpid $$
+
+        Get the PID of the first ancestor of the current process, if there
+        is no ancestor named "not_a_process."
+
+                rpid $$ not_a_process
+
+        Get the PID of the current process itself, if it is named
+        "current_process."
+
+                rpid $$ current_process
 '
 
 # Validate the arguments
@@ -51,13 +61,19 @@ get_info() {
   ppid="${ppid%%[[:space:]]}"
 }
 
-next_pid="${pid}"
-while [[ "${name}" != "${root_name}" && "${ppid}" -ne 1 ]]; do
-  get_info "${next_pid}";
-  name_pid="${next_pid}"
-  next_pid="${ppid}"
+prev_pid="${pid}"
+current_pid="${pid}"
+while [[ "${name}" != "${root_name}" && -r "/proc/${current_pid}/status" ]]; do
+  mapfile info < \
+    <(grep --null -E -m 2 '^(Name|PPid):' "/proc/${current_pid}/status" \
+      | sort | cut -f 2)
+  name="${info[0]##[[:space:]]}"
+  name="${name%%[[:space:]]}"
+  prev_pid="${current_pid}"
+  current_pid="${info[1]##[[:space:]]}"
+  current_pid="${current_pid%%[[:space:]]}"
 done
 
+printf '%s\n' "${prev_pid}"
 if [[ "${name}" != "${root_name}" ]]; then exit 1; fi
-printf '%s\n' "${name_pid}"