How does the ps command work?

On Linux, the ps command works by reading files in the proc filesystem. The directory /proc/PID contains various files that provide information about process PID. The content of these files is generated on the fly by the kernel when a process reads them.

You can find documentation about the entries in /proc in the proc(5) man page and in the kernel documentation.

You can find this out by yourself by observing what the ps command does with strace, a command that lists the system calls made by a process.

% strace -e open ps
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
open("/lib/x86_64-linux-gnu/libprocps.so.3", O_RDONLY|O_CLOEXEC) = 3
open("/lib/x86_64-linux-gnu/libdl.so.2", O_RDONLY|O_CLOEXEC) = 3
open("/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
open("/sys/devices/system/cpu/online", O_RDONLY|O_CLOEXEC) = 3
open("/usr/lib/locale/locale-archive", O_RDONLY|O_CLOEXEC) = 3
open("/proc/self/stat", O_RDONLY)       = 3
open("/proc/uptime", O_RDONLY)          = 3
open("/proc/sys/kernel/pid_max", O_RDONLY) = 4
open("/proc/meminfo", O_RDONLY)         = 4
open("/proc/1/stat", O_RDONLY)          = 6
open("/proc/1/status", O_RDONLY)        = 6
open("/proc/2/stat", O_RDONLY)          = 6
open("/proc/2/status", O_RDONLY)        = 6
open("/proc/3/stat", O_RDONLY)          = 6
open("/proc/3/status", O_RDONLY)        = 6
…

% strace -e open ps
…
open("/proc/1/stat", O_RDONLY)          = 6
open("/proc/1/status", O_RDONLY)        = 6
open("/proc/1/cmdline", O_RDONLY)       = 6
…

You might want to take a look in the /proc folder:
Every process running on your machine has a subfolder here, with plenty of files (the most useful IMO being comm, that gives the name of the process.)


It works by using libprocps.so library.

The main format is :

(A) start (calling openproc())

(B) reading info of process (calling readproc() for each one)

(C) stop ( calling closeproc())

Using libprocps.so gives advantages (for example, freeing you of coding a bunch of "parsing" functions) and disadvantages (maybe you want less info than gathered by readproc() calls).

A program using libprocps.so has this basic format.

    #include <proc/readproc.h>
         :
    int main()
   {
         :
       PROCTAB *proctab = openproc(<OPTIONS>) ;
         :
         :
       proc_t procinfo ;
       memset(&procinfo, 0, sizeof(procinfo)) ;
       while(readproc(proctab, &procinfo) != nullptr)
       {
          <do something with procinfo data>
       }
         :
         :
       closeproc(proctab) ;
       return 0 ;
    }

procinfo will hold all info for a process(like utime, stime, priority, nice, ppid, etc) already in numeric format. If you downloaded the sources, proc_t struct is defined into readproc.h

The OPTIONS you can use in the openproc() call are bitwise-or flags, so you can use one or more of then, as :

    PROCTAB *proctab = openproc(PROC_FILLMEM | PROC_FILLCOM) ;

They are defined into readproc.h too (search for '#define PROC_FILLMEM').

Tags:

Linux

Ps