linux 列出主进程的所有父进程

vi4fp9gy  于 2022-12-03  发布在  Linux
关注(0)|答案(1)|浏览(187)

我正在列出Main()进程的所有父进程的PID和命令。我应该在main()函数中写什么,以便我可以列出根进程?
当前代码:

#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);
}

如何仅通过更改main()函数的内容来处理此问题?
我得到的输出:

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

我想得到的输出是这样的(列出主进程的所有父进程):

-------------------------------------------------------------------
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
-----------------------------------------------------------------
tag5nh1u

tag5nh1u1#

正如注解中所指出的,在使用pidppid的值之后,用父PID替换当前PID,并且只要该值不为零就循环。
如何仅通过更改main()函数的内容来处理这个问题?
仅将程序中的main更改为

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);
}

产生输出:

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

相关问题