I'm making a program that can see if page faults occur in some processes,
and my method to do this is to get all process's PIDs and see rss
, maj_flt
etc. by seeking in every single /proc/[PID]
, checking if there's a change in total maj_flt
.
But in order to get all running process's PIDs, I need to get those directly from my C program, without using existing shell commands like ps
, top
etc.
Does anyone know where the running PID data exists in /proc
or somewhere else? Or if there's another way to do this, like getting it by system call function in my C program?
There is no syscall that exposes a list of PIDs unfortunately. The way you are supposed to get this information in Linux is through the /proc
virtual filesystem.
If you want a list of PIDs of currently running processes, you can use opendir()
and readdir()
to open /proc
and iterate over the list of files/directories in there. Then you can check for directories having a filename that is a number. After checking, you can then open /proc/<PID>/stat
to get the information you want (in particular, you want the 12th field majflt
).
Here's a simple working example (some more error checking and adjustments might be needed):
#include <sys/types.h>
#include <dirent.h>
#include <stdio.h>
#include <ctype.h>
// Helper function to check if a struct dirent from /proc is a PID directory.
int is_pid_dir(const struct dirent *entry) {
const char *p;
for (p = entry->d_name; *p; p++) {
if (!isdigit(*p))
return 0;
}
return 1;
}
int main(void) {
DIR *procdir;
FILE *fp;
struct dirent *entry;
char path[256 + 5 + 5]; // d_name + /proc + /stat
int pid;
unsigned long maj_faults;
// Open /proc directory.
procdir = opendir("/proc");
if (!procdir) {
perror("opendir failed");
return 1;
}
// Iterate through all files and directories of /proc.
while ((entry = readdir(procdir))) {
// Skip anything that is not a PID directory.
if (!is_pid_dir(entry))
continue;
// Try to open /proc/<PID>/stat.
snprintf(path, sizeof(path), "/proc/%s/stat", entry->d_name);
fp = fopen(path, "r");
if (!fp) {
perror(path);
continue;
}
// Get PID, process name and number of faults.
fscanf(fp, "%d %s %*c %*d %*d %*d %*d %*d %*u %*lu %*lu %lu",
&pid, &path, &maj_faults
);
// Pretty print.
printf("%5d %-20s: %lu\n", pid, path, maj_faults);
fclose(fp);
}
closedir(procdir);
return 0;
}
Sample output:
1 (systemd) : 37
35 (systemd-journal) : 1
66 (systemd-udevd) : 2
91 (dbus-daemon) : 4
95 (systemd-logind) : 1
113 (dhclient) : 2
143 (unattended-upgr) : 10
148 (containerd) : 11
151 (agetty) : 1
...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With