Home > Software design >  Listing all the parent processes of the main process
Listing all the parent processes of the main process

Time:11-29

I am listing PIDs and commands of all parent processes of Main() process. What should I write inside the main() function so that I can list up to the root process?

Current code:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <string.h>


void get_ppid(const pid_t pid, pid_t * ppid) {
   char buffer[1024];
   sprintf(buffer, "/proc/%d/stat", pid);
   FILE* fp = fopen(buffer, "r");
   if (fp) {
      size_t size = fread(buffer, sizeof (char), sizeof (buffer), fp);
      if (size > 0) {
         // http://man7.org/linux/man-pages/man5/proc.5.html -> /proc/[pid]/stat
         strtok(buffer, " "); // (1) pid  %d
         strtok(NULL, " "); // (2) comm  %s
         strtok(NULL, " "); // (3) state  %c
         char * s_ppid = strtok(NULL, " "); // (4) ppid  %d
         *ppid = atoi(s_ppid);
      }
      fclose(fp);
   }
}

char* get_name(const pid_t pid){
    char path[1024] = "";
    char pids[20];
    sprintf(pids, "%d", pid);

    strcat(path, "/proc/");
    strcat(path, pids);
    strcat(path, "/cmdline");

    FILE* fp = fopen(path, "r");
    if(fp == NULL){
      printf("Cannot open the file!");
      exit(1);
   }

   char* pname = malloc(1024);
   fscanf(fp, "%s", pname);
   return pname;
}

void print_process_info(const pid_t pid, pid_t ppid, char* pname){
    printf("%-20d%-20d%-50s\n", pid, ppid, pname);
}

void print_header(){
    printf("%-20s%-20s%-50s\n", "ID", "Parent ID", "Command");
}


int main(int argc, char *argv[])
{
   int pid =  getpid();
   int ppid;
   get_ppid(pid, &ppid);
   char* pname = get_name(pid);

   print_header();
   print_process_info(pid, ppid, pname);
   free(pname);
}

How can I handle this just by changing the content of the main() function?

The output I got:

ID            |     Parent ID      |     Command                                              
782663        |      782612        |     ./main

The output I want to get is this (listing all the parent processes of the main process):

-------------------------------------------------------------------
ID          |        Parent ID    |       Command                                              
783001      |         782612      |        ./main                                            
782612      |        609630       |       /bin/bash                                         
609630      |        609333       |       /usr/bin/kate                                     
609333      |        609170       |       /usr/bin/ksmserver                                
609170      |        1            |       /lib/systemd/systemd
            |
1           |        0            |       /sbin/init
-----------------------------------------------------------------

CodePudding user response:

As pointed out in the comments, after using the values of pid and ppid, replace the current PID with the parent's PID, and loop as long as that isn't zero.

How can I handle this just by changing the content of the main() function?

Changing only main in your program to this

int main(int argc, char *argv[])
{
    int pid =  getpid();

    do {
        int ppid;
        get_ppid(pid, &ppid);
        char *pname = get_name(pid);

        print_header();
        print_process_info(pid, ppid, pname);
        free(pname);

        pid = ppid;
    } while (pid != 0);
}

produces the output:

ID                  Parent ID           Command                                           
71678               61852               ./a.out                                           
ID                  Parent ID           Command                                           
61852               61829               bash                                              
ID                  Parent ID           Command                                           
61829               952                 /usr/lib64/gnome-terminal/gnome-terminal-server   
ID                  Parent ID           Command                                           
952                 1                   /usr/lib/systemd/systemd                          
ID                  Parent ID           Command                                           
1                   0                   /usr/lib/systemd/systemd
  • Related