Программирование для Linux. Профессиональный подход
Шрифт:
struct stat file_info;
int rval;
/* Открытие файла /etc/issue */
input_fd = open("/etc/issue", O_RDONLY);
if (input_fd == -1)
system_error("open");
/* Получение информации о файле. */
rval = fstat(input_fd, &file_info);
if (rval == -1)
/* не удалось открыть файл или прочитать данные
из него. */
write(fd, error_page, strlen(error_page));
else {
int rval;
off_t offset = 0;
/* Запись начала страницы */
write(fd, page_start, strlen(page_start));
/* Копирование данных из файла /etc/issue
в клиентский сокет. */
rval = sendfile(fd, input_fd, &offset, file_info.st_size);
if (rval == -1)
/* При отправке файла /etc/issue произошла ошибка.
Выводим соответствующее сообщение. */
write(fd, error_message, strlen(error_message));
/* Конец страницы. */
write(fd, page_end, strlen(page_end));
}
close(input_fd);
}
Сначала модуль пытается открыть файл
/etc/issue
. Если это не удалось, клиенту возвращается сообщение об ошибке. В противном случае посылается начальный код HTML-страницы, содержащийся в переменной page_start
, затем — содержимое файла /etc/issue
(это делается с помощью функции sendfile
, о которой рассказывалось в разделе 8.12. "Функция sendfile: быстрая передача данных") и, наконец конечный код HTML-страницы, содержащийся в переменной page_end
. Этот модуль можно легко настроить на отправку любого другого файла. Если файл содержит HTML-страницу, переменные
page_start
и page_end
будут не нужны. 11.3.3. Отображение объема свободного дискового пространства
Модуль
diskfree.so
(исходный текст приведен в листинге 11.8) генерирует страницу с информацией о свободном дисковом пространстве в файловых системах, смонтированных на серверном компьютере. Эта информация берется из выходных данных команды df -h
. Как и в модуле issue.so
, выходные данные заключаются в тэги <pre></pre>
. Листинг 11.8. (diskfree.c) Серверный модуль, отображающий информацию о свободном дисковом пространстве
#include <string.h>
#include <sys/types.h>
#include <sys/wait.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";
void module_generate(int fd) {
pid_t child_pid;
int rval;
/* Запись начала страницы. */
write(fd, page_start, strlen(page_start));
/* Создание дочернего процесса. */
child_pid = fork;
if (child_pid == 0) {
/* Это дочерний процесс. */
/* Подготовка списка аргументов команды df. */
char* argv[] = { "/bin/df, "-h", NULL };
/* Дублирование потоков stdout и stderr для записи данных
в клиентский сокет. */
rval = dup2(fd, STDOUT_FILENO);
if (rval == -1)
system_error("dup2");
rval = dup2(fd, STDERR_FILENO);
if (rval == -1)
system_error("dup2");
/* Запуск команды df, отображающей объем свободного
пространства в смонтированных файловых системах. */
execv(argv[0], argv);
/* Функция execv возвращает управление в программу только
при возникновении ошибки. */
system_error("execv");
} else if (child_pid > 0) {
/* Это родительский процесс, дожидаемся завершения дочернего
процесса. */
rval = waitpid(child_pid, NULL, 0);
if (rval == -1)
system_error("waitpid");
} else
/* Вызов функции fork завершился неудачей. */
system_error("fork");
/* запись конца страницы. */
write(fd, page_end, strlen(page_end));
}
В то время как модуль
issue.so
посылает содержимое файла с помощью функции sendfile
, данный модуль должен вызвать внешнюю команду и перенаправить результаты ее работы клиенту. Для этого модуль придерживается такой последовательности действий. 1. Сначала с помощью функции
fork
создается дочерний процесс (см. раздел 3.2.2. "Функции fork и exec").
Поделиться:
Популярные книги
Кодекс Охотника. Книга XXXIX
39. Кодекс Охотника
Фантастика:
фэнтези
попаданцы
боевая фантастика
5.00
рейтинг книги
Я до сих пор царь. Книга XXXII
32. Дорогой барон!
Фантастика:
юмористическое фэнтези
аниме
попаданцы
5.00
рейтинг книги
Барон ненавидит правила
8. Закон сильного
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Представь себе… Беседы о деньгах, политике и жизни вообще
Религия и эзотерика:
самосовершенствование
5.00
рейтинг книги
Точка Бифуркации VI
6. ТБ
Фантастика:
фэнтези
попаданцы
аниме
5.40
рейтинг книги
Свадьба на выбор, или Женихи в ассортименте
Любовные романы:
современные любовные романы
7.71
рейтинг книги
Неучтенный элемент. Том 10
10. Антимаг. Вне системы
Фантастика:
фэнтези
5.25
рейтинг книги
Литрпг
5.00
рейтинг книги
Тринадцатый
1. Видящий смерть
Фантастика:
фэнтези
попаданцы
аниме
7.33
рейтинг книги
Записки уцелевшего
Документальная литература:
биографии и мемуары
7.00
рейтинг книги
Мифы и правда о плане Барбаросса
Анатомия армии
Научно-образовательная:
история
5.00
рейтинг книги
Цикл "Идеальный мир для Лекаря". Компиляция. Книги 1-30
Лекарь
Фантастика:
боевая фантастика
юмористическое фэнтези
аниме
фэнтези
5.00
рейтинг книги
Игра киллера
Детективы:
боевики
6.25
рейтинг книги
Законы рода
1. Граф Берестьев
Фантастика:
фэнтези
боевая фантастика
аниме
4.75