Программирование для Linux. Профессиональный подход
Шрифт:
По умолчанию серверные модули загружаются из каталога, где находится исполняемый файл. Этот каталог определяется с помощью функции
get_self_executable_directory
. Данную установку можно переопределить с помощью опции – -module
(– m
). В таком случае проверяется, является ли указанный каталог доступным. По умолчанию развернутые сообщения не отображаются, если не указать опцию
– -verbose
(– v
). ■ Если пользователь ввел опцию
– -help
(– h
) или указал неправильную опцию, вызывается функция print_usage
,
11.3. Модули
В дополнение к основной программе созданы четыре модуля, в которых реализованы функции сервера. Чтобы создать собственный модуль, достаточно определить функцию
module_generate
, которая будет возвращать HTML-код. 11.3.1. Отображение текущего времени
Модуль
time.so
(исходный текст приведен в листинге 11.6) генерирует простую страницу, где отображается текущее время на сервере. В функции module_generate
вызывается функция gettimeofday
, возвращающая значение текущего времени (см. раздел 8.7, "Функция gettimeofday: системные часы"), после чего функции localtime
и strftime
преобразуют это значение в текстовый формат. Полученная строка встраивается в шаблон HTML-страницы page_template. Листинг 11.6. (time.c) серверный модуль, отображающий текущее время
#include <assert.h>
#include <stdio.h>
#include <sys/time.h>
#include <time.h>
#include "server.h"
/* шаблон HTML-страницы, генерируемой данным модулем. */
static char* page_template =
"<html>\n"
" <head>\n"
" <meta http-equiv=\"refresh\" content=\"5\">\n"
" </head>\n"
" <body>\n"
" The current time is %s \n"
" </body>\n"
"</html>\n";
void module_generate(int fd) {
struct timeval tv;
struct tm* ptm;
char time_string[40];
FILE* fp;
/* Определение времени суток и заполнение структуры типа tm. */
gettimeofday(&tv, NULL);
ptm = localtime(&tv.tv_sec);
/* Получение строкового представления времени с точностью
до секунды. */
strftime(time_string, sizeof(time_string), "%H:%M:%S", ptm);
/* Создание файлового потока, соответствующего дескриптору
клиентского сокета. */
fp = fdopen(fd, "w");
assert(fp != NULL);
/*
Запись HTML-страницы. */
fprintf(fp, page_template, time_string);
/* Очистка буфера потока */
fflush(fp);
}
Для удобства в этом модуле используются стандартные библиотечные функции ввода-вывода. Функция
fdopen
возвращает указатель потока (FILE*
), соответствующий дескриптору клиентского сокета (подробнее об этом рассказывается в приложении Б, "Низкоуровневый ввод-вывод"). Для отправки страницы клиенту вызывается обычная функция fprintf
, а функция fflush
предотвращает потерю данных в случае закрытия сокета. HTML-страница, возвращаемая модулем
time.so
, содержит в заголовке тэг <meta>
, который служит клиенту указанием перезагружать страницу каждые 5 секунд. Благодаря этому клиент всегда будет знать точное время. 11.3.2. Отображение версии Linux
Модуль
issue.so
(исходный текст приведен в листинге 11.7) выводит информацию о дистрибутиве Linux, с которым работает сервер. Традиционно эта информация хранится в файле /etc/issue
. Модель посылает клиенту Web-страницу с содержимым файла, заключенным в тэге <pre></pre>
. Листинг 11.7. (issue.c) Серверный модуль, отображающий информацию о дистрибутиве Linux
#include <fcntl.h>
#include <string.h>
#include <sys/sendfile.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include "server.h"
/* HTML-код начала генерируемой страницы. */
static char* page_start =
"<html>\n"
" <body>\n"
" <pre>\n";
/* HTML-код конца генерируемой страницы. */
static char* page_end =
" </pre>\n"
" </body>\n"
"</html>\n";
/* HTML-код страницы, сообщающей о том, что
при открытии файла /etc/issue произошла ошибка. */
static char* error_page =
"<html>\n"
" <body>\n"
" Error: Could not open /etc/issue.\n"
" </body>\n"
"</html>\n";
/* Сообщение об ошибке. */
static char* error_message =
"Error reading /etc/issue.";
void module_generate(int fd) {
int input_fd;
Поделиться:
Популярные книги
Моя на одну ночь
Любовные романы:
современные любовные романы
короткие любовные романы
5.50
рейтинг книги
Черный Маг Императора 8
8. Черный маг императора
Фантастика:
юмористическое фэнтези
попаданцы
аниме
5.00
рейтинг книги
Измена. Отбор для предателя
1. Отбор для предателя
Фантастика:
фэнтези
5.00
рейтинг книги
Кодекс Крови. Книга II
2. РОС: Кодекс Крови
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Шаг в бездну
3. Перешагнуть пропасть
Фантастика:
фэнтези
космическая фантастика
7.89
рейтинг книги
Часовая битва
6. Часодеи
Детские:
детская фантастика
9.38
рейтинг книги
Вечная Война. Книга II
2. Вечная война.
Фантастика:
юмористическая фантастика
космическая фантастика
8.37
рейтинг книги
Хроники странного королевства. Вторжение. (Дилогия)
110. В одном томе
Фантастика:
фэнтези
9.38
рейтинг книги
Часовой ключ
1. Часодеи
Фантастика:
фэнтези
9.36
рейтинг книги
Инвестиго, из медика в маги
1. Инвестиго
Фантастика:
фэнтези
городское фэнтези
попаданцы
5.00
рейтинг книги
Кротовский, может, хватит?
3. РОС: Изнанка Империи
Фантастика:
попаданцы
альтернативная история
аниме
7.50
рейтинг книги
Драконий подарок
1. Королевская академия Драко
Любовные романы:
любовно-фантастические романы
7.30
рейтинг книги
Очешуеть! Я - жена дракона?!
Фантастика:
юмористическая фантастика
5.43
рейтинг книги
Идеальный мир для Лекаря 9
9. Лекарь
Фантастика:
боевая фантастика
юмористическое фэнтези
6.00