Файловая система /proc
Помимо файловой системы /dev в Linux есть еще один источник необычных файлов – файловая система /proc. С помощью этой файловой системы можно получить множество ценных сведений о состоянии различных устройств и системных объектов (модулей ядра, например) а также о выполняющихся процессах (собственно, отсюда и происходит ее название).
Сведения об устройствах понадобятся, вероятнее всего, только всяким настраивающим/диагностическим утилитам. Мы же рассмотрим некоторые элементы системы /proc, которые могут пригодиться в программах самого разного назначения. Данные о каждом процессе хранятся в специальной поддиректории директории /proc, с именем, соответствующим численному значению идентификатора процесса. В директории процесса находятся несколько файлов и поддиректорий, из которых можно почерпнуть данные о нем (см. таблицу 2)
cmdline | файл | Командная строка, использовавшаяся при запуске процесса. |
cwd | символическая ссылка | Указывает на директорию процесса |
environ | файл | Список переменных окружения для данного процесса |
exe | символическая ссылка | Указывает на файл, хранящий образ процесса |
fd | директория | Ссылки на файлы, используемые процессом |
root | гибкая ссылка | Указывает на корень файловой системы процесса |
stat | файл | Различные сведения о процессе |
Таблица 2. Файлы и дочерние каталоги /proc/<PID>, позволяющие получить различную информацию о процессе.
Если вы не root, то доступ ко многим поддиректориям процессов будет вам запрещен, но к своей собственной поддиректории процесс может получить доступ всегда. Как найти свою поддиректорию? С помощью getpid(2) процесс может узнать свой идентификатор и сконструировать путь к поддиректории, но есть и более простой способ. Помимо поддиректорий с именами, соответствующими идентификаторам процессов, каждый процесс «видит» в директории /proc поддиректорию-ссылку self, которая указывает на каталог с его данными. Использование данных из директории процесса мы рассмотрим на примере небольшой программы printenv, которая распечатывает в стандартный поток вывода полный список своих переменных окружения.
include <stdio.h> #define BUF_SIZE 0x100 int main(int argc, char * argv[]) { char buf[BUF_SIZE]; int len, i; FILE * f; f = fopen("/proc/self/environ", "r"); while((len = fread(buf, 1, BUF_SIZE-1, f)) > 0) { for (i = 0; i < len; i++) if (buf[i]==0) buf[i] = 10; buf[len] = 0; printf("%s", buf); } fclose(f); return 0; }
Строки в файле environ разделены не символами перевода строки (имеющим код 10 или 0x0A), а нулями.