Выбрать главу

Функция module_generate() определяет идентификаторы процессов, проверяя содержимое файловой системы /proc. Для получения и анализа списка каталогов вызываются функции opendir() и readdir() (описаны в приложении Б, "Низкоуровневый ввод-вывод''). Из данного списка отбираются элементы, имена которых состоят из одних цифр: это каталоги процессов.

Поскольку в таблице может содержаться достаточно большое число строк, последовательная запись их в сокет с помощью функции write() приведет к ненужному повышению трафика. Для оптимизации числа передаваемых пакетов используется функция writev() (описана в приложении Б, "Низкоуровневый ввод-вывод"). Для нее создается массив vec, состоящий из элементов типа iovec. Так как число процессов не известно заранее приходится начинать с маленького массива и увеличивать его по мере необходимости. В переменной vec_length содержится число используемых элементов массива vec, а в переменной vec_size — число выделенных элементов. Когда эти переменные становятся почти равными друг другу, размер массива удваивается с помощью функции xrealloc(). По окончании работы с массивом удаляются все адресуемые в нем строки, а также сам массив.

11.4. Работа с сервером

Если бы демонстрационную программу нужно было распространять в виде исходных текстов, сопровождать и переносить на другие платформы, потребовалось бы упаковать ее с помощью GNU-утилит Automake и Autoconf. Но их рассмотрение выходит за рамки нашей книги.

11.4.1. Файл Makefile

Вместо утилиты Autoconf мы воспользуемся простым файлом Makefile, совместимым с GNU-утилитой Make.[39] Этот файл упростит компиляцию и компоновку сервера и его модулей. Содержимое файла показано в листинге 11.10.

Листинг 11.10. (Makefile) Файл конфигурации сервера

### Конфигурация. ##############################################

# Стандартные параметры компилятора языка С.

CFLAGS = -Wall -g

# Исходные файлы сервера.

SOURCES = server.c module.c common.c main.c

# Соответствующие объектные файлы.

OBJECTS = $(SOURCES:.c=.o)

# Совместно используемые библиотеки серверных модулей.

MODULES = diskfree.so issue.so processes.so time.so

### Правила. ####################################################

# Служебный целевой модуль.

.PHONY: all clean

# Стандартный целевой модуль: компиляция всех файлов.

alclass="underline" server $(MODULES)

# Удаление всех компонентов.

clean:

    rm -f $(OBJECTS) $(MODULES) server

# Главная серверная программа, должна компоноваться с флагами

# -Wl,-export-dynamic, чтобы динамически загружаемые модули могли

# находить в программе символические константы. Подключается также

# библиотека libdl, в которой находятся функции динамической

# загрузки.

server: $(OBJECTS)

    $(CC) $(CFLAGS) Wl,-export-dynamic -о $@ $^ -ldl

# Все объектные файлы сервера зависят от файла server.h.

# Используем стандартное правило создания объектных файлов из

# исходных файлов.

$(OBJECTS): server.h

# Правило создания совместно используемых библиотек из

# соответствующих исходных файлов, компилируем с флагом -fPIC и

# генерируем совместно используемый объектный файл.

$(MODULES): \

%.so: %.c server.h

    $(CC) $(CFLAGS) -fPIC -shared -o $@ $<

В файле Makefile есть следующие целевые модули.

■ Модуль all (используется по умолчанию при вызове файла Makefile без аргументов, так как стоит первым) содержит исполняемый файл server и все серверные модули. Последние перечислены в переменной MODULES.

■ Модуль clean предназначен для удаления всех скомпилированных компонентов.

■ Модуль server подключает к проекту исполняемый файл сервера. Компилируются и компонуются исходные файлы, перечисленные в переменной SOURCES.

■ Последнее правило представляет собой шаблон компиляции совместно используемых файлов серверных модулей.

Обратите внимание на то, что исходные файлы серверных модулей компилируются с флагом -fPIC, так как они включаются в совместно используемые библиотеки (см. раздел 2.3.2, "Совместно используемые библиотеки").

Исполняемый файл server компонуется с флагом -Wl,-export-dynamic. Благодаря этому файл будет экспортировать свои символические константы, что позволит динамически загружаемым модулям ссылаться на функции, находящиеся в файле common.c.

вернуться

39

Эта утилита входит в состав Linux.