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