Программирование для 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;
Поделиться:
Популярные книги
Белые погоны
3. Гибрид
Фантастика:
фэнтези
попаданцы
технофэнтези
аниме
5.00
рейтинг книги
Черный дембель. Часть 1
1. Черный дембель
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Лишняя дочь
Любовные романы:
любовно-фантастические романы
8.22
рейтинг книги
Темный Лекарь 5
5. Темный Лекарь
Фантастика:
фэнтези
аниме
5.00
рейтинг книги
Последний из рода Демидовых
Фантастика:
детективная фантастика
попаданцы
аниме
5.00
рейтинг книги
Чиновникъ Особых поручений
6. Александр Агренев
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Попаданка в академии драконов 4
4. Попаданка в академии драконов
Любовные романы:
любовно-фантастические романы
7.47
рейтинг книги
Боги, пиво и дурак. Том 6
6. Боги, пиво и дурак
Фантастика:
фэнтези
попаданцы
5.00
рейтинг книги
Курсант: Назад в СССР 10
10. Курсант
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Сделай это со мной снова
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Болотник 2
2. Болотник
Фантастика:
попаданцы
альтернативная история
6.25
рейтинг книги
Камень Книга двенадцатая
12. Камень
Фантастика:
боевая фантастика
городское фэнтези
аниме
фэнтези
5.00
рейтинг книги
Небо для Беса
3. Самбисты
Любовные романы:
современные любовные романы
5.25
рейтинг книги
Надуй щеки! Том 4
4. Чеболь за партой
Фантастика:
попаданцы
уся
дорама
5.00