11.2. Реализация
11.2. Реализация
Во всех более-менее сложных C-программах требуется тщательно продумать организацию, чтобы сохранить модульность и обеспечить удобство сопровождения. Наша демонстрационная программа разделена на четыре главных исходных файла.
В каждом исходном файле экспортируются функции и переменные, используемые в других частях программы. Для простоты все они объявлены в одном файле заголовков: server.h (листинг 11.1). Функции, применяемые в рамках только одного модуля, объявлены со спецификатором static и не включены в файл server.h.
Листинг 11.1. (server.h) Объявления функций и переменных
#ifndef SERVER_H
#define SERVER_H
#include <netinet/in.h>
#include <sys/types.h>
/*** Символические константы файла common.c. ********************/
/* Имя программы. */
extern const char* program_name;
/* Если не равна нулю, отображаются развернутые сообщения. */
extern int verbose;
/* Напоминает функцию malloc(), не прерывает работу программы,
если выделить память не удалось. */
extern void* xmalloc(size_t size);
/* Напоминает функцию realloc(), но прерывает работу программы,
если выделить память не удалось */
extern void* xrealloc(void* ptr, size_t size);
/* Напоминает функцию strdup(), но прерывает работу программы,
если выделить память не удалось. */
extern char* xstrdup(const char* s);
/* Выводит сообщение об ошибке заданного системного вызова
и завершает работу программы. */
extern void system_error(const char* operation);
/* Выводит сообщение об ошибке и завершает работу программы. */
extern void error(const char* cause, const char* message);
/* Возвращает имя каталога, содержащего исполняемый файл
программы. Поскольку возвращается указатель на область памяти,
вызывающая подпрограмма должна удалить ее с помощью
функции free(). В случае неудачи выполнение программы
завершается. */
extern char* get_self_executable_directory();
/*** Символические константы файла module.с *********************/
/* Экземпляр загруженного серверного модуля. */
struct server_module {
/* Дескриптор библиотеки, в которой находится модуль. */
void* handle;
/* Описательное имя модуля. */
const char* name;
/* Функция, генерирующая HTML-код для модуля. */
void (*generatе_function)(int);
};
/* Каталог, из которого загружаются модули. */
extern char* module_dir;
/* Функция, пытающаяся загрузить указанный серверный модуль.
Если модуль существует, возвращается структура
с его описанием, в противном случае возвращается NULL. */
extern struct server_module* module_open(const char* module_path);
/* Закрытие модуля и удаление объекта MODULE. */
extern void module_close(struct server_module* module);
/*** Символические константы файла server.c. ********************/
/* Запуск сервера по адресу LOCAL_ADDRESS и порту PORT. */
extern void server_run(struct in_addr local_address, uint16_t port);
#endif /* SERVER_H */