Книга: Программирование для Linux. Профессиональный подход

Листинг 11.3. (module.c) Загрузка и выгрузка серверных модулей

Листинг 11.3. (module.c) Загрузка и выгрузка серверных модулей

#include <dlfcn.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "server.h"
char* module_dir;
struct server_module* module_open(const char* module_name) {
 char* module_path;
 void* handle;
 void (*module_generate)(int);
 struct server_module* module;
 /* Формирование путевого имени библиотеки, в которой содержится
    загружаемый модуль. */
 module_path =
  (char*)xmalloc(strlen(module_dir) +
  strlen(module_name) + 2);
 sprintf(module_path, "%s/%s", module_dir, module_name);
 /* Попытка открыть файл MODULE_PATH как совместно используемую
    библиотеку. */
 handle = dlopen(module_path, RTLD_NOW);
 free (module_path);
 if (handle == NULL) {
  /* Ошибка: либо путь не существует, либо файл не является
     совместно используемой библиотекой. */
  return NULL;
 }
 /* Чтение константы module_generate из библиотеки. */
 module_generatе =
  (void(*)int))dlsym(handle,
  "module_generate");
 /* Проверяем, найдена ли константа. */
 if (module_generate == NULL) {
  /* Константа отсутствует в библиотеке. Очевидно, файл не
     является серверным модулем. */
  dlclose(handle);
  return NULL;
 }
 /* Выделение и инициализация объекта server_module. */
 module =
  (struct server_module*)xmalloc
  (sizeof (struct server_module));
 module->handle = handle;
 module->name = xstrdup(module_name);
 module->generate_function = module_generate;
 /* Успешное завершение функции. */
 return module;
}
void module_close(struct server_module* module) {
 /* Закрытие библиотеки. */
 dlclose(module->handle);
 /* Удаление строки с именем модуля. */
 free((char*)module->name);
 /* Удаление объекта module. */
 free(module);
}

Каждый модуль содержится в файле совместно используемой библиотеки (см. раздел 2.3.2, "Совместно используемые библиотеки") и должен экспортировать функцию module_generate(). Эта функция генерирует HTML-код Web-страницы и записывает его в сокет, дескриптор которого передан ей в качестве аргумента.

В файле module.c определены две функции.

? Функция module_open() пытается загрузить серверный модуль с указанным именем. Файл модуля имеет расширение .so, так как это совместно используемая библиотека. Функция открывает библиотеку с помощью функции dlopen() и ищет в библиотеке константу module_generate посредством функции dlsym() (описаны в разделе 2.3.6, "Динамическая загрузка и выгрузка"). Если библиотеку не удалось открыть или в ней не обнаружена экспортируемая константа module_generate, возвращается значение NULL. В противном случае выделяется и возвращается объект module.

? Функция module_close() закрывает совместно используемую библиотеку, соответствующую указанному модулю, и удаляет объект module.

В файле module.c определена также глобальная переменная module_dir. В ней записано имя каталога, в котором функция module_open() будет искать совместно используемые библиотеки.

Оглавление книги


Генерация: 1.171. Запросов К БД/Cache: 3 / 1
поделиться
Вверх Вниз