7.1 Extracting Information from /proc

Most of the entries in /proc provide information formatted to be readable by humans, but the formats are simple enough to be easily parsed. For example, /proc/cpuinfo contains information about the system CPU (or CPUs, for a multiprocessor machine). The output is a table of values, one per line, with a description of the value and a colon preceding each value.

For example, the output might look like this:

 
% cat /proc/cpuinfo 
processor       : 0 
vendor_id       : GenuineIntel 
cpu family      : 6 
model           : 5 
model name      : Pentium II (Deschutes) 
stepping        : 2 
cpu MHz         : 400.913520 
cache size      : 512 KB 
fdiv_bug        : no 
hlt_bug         : no 
sep_bug         : no 
f00f_bug        : no 
coma_bug        : no 
fpu             : yes 
fpu_exception   : yes 
cpuid level     : 2 
wp              : yes 
flags           : fpu vme de pse tsc msr pae mce cx8 apic sep 
mtrr pge mca cmov pat pse36 mmx fxsr 
bogomips        : 399.77 

We'll describe the interpretation of some of these fields in Section 7.3.1, "CPU Information."

A simple way to extract a value from this output is to read the file into a buffer and parse it in memory using sscanf. Listing 7.1 shows an example of this. The program includes the function get_cpu_clock_speed that reads from /proc/cpuinfo into memory and extracts the first CPU's clock speed.

Listing 7.1 (clock-speed.c) Extract CPU Clock Speed from /proc/cpuinfo
#include <stdio.h> 
#include <string.h> 
 
/* Returns the clock speed of the system's CPU in MHz, as reported by 
   /proc/cpuinfo. On a multiprocessor machine, returns the speed of 
   the first CPU. On error returns zero.  */ 
 
float get_cpu_clock_speed () 
{
   FILE* fp; 
   char buffer[1024]; 
   size_t bytes_read; 
   char* match; 
   float clock_speed; 
 
   /* Read the entire contents of /proc/cpuinfo into the buffer.  */ 
   fp = fopen ("/proc/cpuinfo", "r"); 
   bytes_read = fread (buffer, 1, sizeof (buffer), fp); 
   fclose (fp); 
   /* Bail if read failed or if buffer isn't big enough.  */ 
   if (bytes_read == 0 || bytes_read == sizeof (buffer)) 
     return 0; 
   /* NUL-terminate the text.  */ 
   buffer[bytes_read] == '\0'; 
   /* Locate the line that starts with "cpu MHz".  */ 
   match = strstr (buffer, "cpu MHz"); 
   if (match == NULL) 
     return 0; 
   /* Parse the line to extract the clock speed.  */ 
   sscanf (match, "cpu MHz  :  %f", &clock_speed); 
   return clock_speed; 
} 
 
 
 
 int main () 
{
   printf ("CPU clock speed: %4.0f MHz\n", get_cpu_clock_speed ()); 
   return 0; 
} 

Be aware, however, that the names, semantics, and output formats of entries in the /proc file system might change in new Linux kernel revisions. If you use them in a program, you should make sure that the program's behavior degrades gracefully if the /proc entry is missing or is formatted unexpectedly.