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
