Программирование для 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").
Поделиться:
Популярные книги
Усадьба леди Анны
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Чужая дочь
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Светлая тьма. Советник
6. Светлая Тьма
Фантастика:
юмористическое фэнтези
городское фэнтези
аниме
сказочная фантастика
фэнтези
5.00
рейтинг книги
Двойник Короля
1. Двойник Короля
Фантастика:
попаданцы
аниме
фэнтези
фантастика: прочее
5.00
рейтинг книги
Его нежеланная истинная
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Последний Паладин. Том 2
2. Путь Паладина
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Измена. Наследник для дракона
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Идеальный мир для Лекаря 9
9. Лекарь
Фантастика:
боевая фантастика
юмористическое фэнтези
6.00
рейтинг книги
Мастер темных Арканов
1. Мастер темных арканов
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Адвокат империи
1. Адвокат империи
Фантастика:
городское фэнтези
попаданцы
фэнтези
5.75
рейтинг книги
Кодекс Охотника. Книга XXI
21. Кодекс Охотника
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Вечный. Книга II
2. Вечный
Фантастика:
боевая фантастика
попаданцы
рпг
5.00
рейтинг книги
Законы Рода. Том 3
3. Граф Берестьев
Фантастика:
фэнтези
аниме
5.00
рейтинг книги
Наследник
1. Старицкий
Приключения:
исторические приключения
5.00