Linux implements a special virtual filesystem called /proc that stores information about the kernel, kernel data structures, and the state of each process and associated threads. Remember that in Linux a thread is implemented as a special type of process. The /proc filesystem is stored in memory, not on disk. The majority of the information provided is read-only and can vary greatly from one version of Linux to another. Standard system calls (such as open , read , etc.) can be used by programs to access /proc files.
Linux provides a procinfo command that generates a formatted display of /proc information. Figure 2.23 shows the default output of this command. As would be expected, there is a variety of command-line options for procinfo (check the manual page $ man 8 procinfo for specifics). Additionally, while most of the files in /proc are in a special format, many can be displayed by using the command-line cat utility. [13]
[13] Do not be put off by the fact that the majority of the files in /proc show 0 bytes when a long listing is donekeep in mind this is a not a true filesystem.
Figure 2.23 Typical procinfo output.
linux$ procinfo Linux 2.4.3-12enterprise (root@porky) (gcc 2.96 20000731 ) #1 2CPU [linux] Memory: Total Used Free Shared Buffers Cached Mem: 512928 510436 2492 84 65996 265208 Swap: 1068284 544 1067740 Bootup: Thu Dec 27 12:31:23 2001 Load average: 0.00 0.00 0.00 >1/85 10791 user : 0:12:34.61 0.0% page in : 7194848 nice : 0:00:15.34 0.0% page out: 1714280 system: 0:16:18.81 0.0% swap in : 1 idle : 21d 20:49:43.68 99.9% swap out: 0 uptime: 10d 22:39:26.21 context : 31669318 irq 0: 94556622 timer irq 8: 2 rtc irq 1: 2523 keyboard irq 12: 15009 PS/2 Mouse irq 2: 0 cascade [4] irq 26: 17046596 e100 irq 3: 4 irq 28: 30 aic7xxx irq 4: 6223833 serial irq 29: 30 aic7xxx irq 6: 3 irq 30: 155995 aic7xxx irq 7: 3 irq 31: 918432 aic7xxx
In the /proc file system are a variety of data files and subdirectories. A typical /proc file system is shown in Figure 2.24.
Figure 2.24 Directory listing of a /proc file system.
linux$ ls /proc 1 1083 20706 4 684 9228 dma loadavg stat 1025 1084 20719 494 7 9229 driver locks swaps 1030 1085 20796 499 704 9230 execdomains mdstat sys 10457 1086 20797 5 718 9231 fb meminfo sysvipc 10458 19947 20809 511 752 9232 filesystems misc tty 10459 2 3 526 758 9233 fs modules uptime 1057 20268 32463 6 759 9234 ide mounts version 10717 20547 32464 641 765 9235 interrupts mtrr 10720 20638 32466 653 778 9236 iomem net 10721 20652 32468 655 780 997 ioports partitions 10725 20680 32469 656 795 bus irq pci 10726 20695 32471 657 807 cmdline kcore scsi 10731 20696 32473 658 907 cpuinfo kmsg self 10736 20704 32474 669 9227 devices ksyms slabinfo
Numeric entries, such as 1 or 1025, are process subdirectories for existing processes and contain information specific to the process. Nonnumeric entries, excluding the self entry, have kernel-related information. At this point, a full presentation of the kernel- related entries in /proc would be a bit premature, as many of them reflect constructs (such as shared memory) that are covered in detail in later chapters of the text. The remaining discussion focuses on the process-related entries in /proc .
The /proc/self file is a pointer (symbolic link) to the ID of the current process. Program 2.10 uses the system call readlink (see Table 2.25) to obtain the current process ID from / proc/self .
Program 2.10 Reading the /proc/self file.
File : p2.10.cxx /* Determining Process ID by reading the contents of the symbolic link /proc/self */ + #define _GNU_SOURCE #include #include #include #include 10 using namespace std; const int size = 20; int main( ){ pid_t proc_PID, get_PID; + char buffer[size]; get_PID = getpid( ); readlink("/proc/self", buffer, size); proc_PID = atoi(buffer); cout << "getpid : " << get_PID << endl; 20 cout << "/proc/self : " << proc_PID << endl; return 0; }
Table 2.25. Summary of the readlink System Call.
Include File(s) |
Manual Section |
2 |
||
Summary |
int readlink(const char *path, char *buf, size_t bufsiz); |
|||
Return |
Success |
Failure |
Sets errno |
|
Number of characters read |
-1 |
Yes |
The readlink system call reads the symbolic link referenced by path and stores this data in the location referenced by buf . The bufsiz argument specifies the number of characters to be processed and is most often set to be the size of the location referenced by the buf argument. The readlink system call does not append a null character to its input. If this system call fails, it returns a 1 and sets errno ; otherwise , it returns the number of characters read. In the case of error the values that errno can take on are listed in Table 2.26.
A wide array of data on each process is kept by the operating system. This data is found in the /proc directory in a decimal number subdirectory named for the process's ID. Each process subdirectory includes
Table 2.26. readlink Error Messages.
# |
Constant |
perror Message |
Explanation |
---|---|---|---|
2 |
ENOENT |
No such file or directory |
File does not exist. |
5 |
EIO |
I/O error |
I/O error while attempting read or write to file system. |
12 |
ENOMEM |
Cannot allocate memory |
Out of memory (i.e., kernel memory). |
13 |
EACCES |
Permission denied |
Search permission denied on part of file path. |
14 |
EFAULT |
Bad address |
Path references an illegal address. |
20 |
ENOTDIR |
Not a directory |
Part of the specified path is not a directory. |
22 |
EINVAL |
Invalid argument |
|
36 |
ENAMETOOLONG |
File name too long |
The path value exceeds system path/ file name length. |
40 |
ELOOP |
Too many levels of symbolic links |
The perror message says it all. |
As noted, the cmdline file has the argument list for the process. This same data is passed to the function main as argv . The data is stored as a single character string with a null character separating each entry. On the command line, the tr utility can be used to translate the null characters into newlines to make the contents of the file easier to read. For example, the command-line sequence
linux$ cat /proc/cmdline tr "
linux$ cat /proc/cmdline tr "