Программирование для 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").
Поделиться:
Популярные книги
Я уже царь. Книга XXIX
29. Дорогой барон!
Фантастика:
юмористическое фэнтези
аниме
попаданцы
5.00
рейтинг книги
Подросток
Проза:
русская классическая проза
9.09
рейтинг книги
Товарищ "Чума" 6
6. Товарищ "Чума"
Фантастика:
городское фэнтези
попаданцы
альтернативная история
5.00
рейтинг книги
Сирийский рубеж 3
7. Рубеж
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Локки 4 Потомок бога
4. Локки
Фантастика:
аниме
фэнтези
5.00
рейтинг книги
Алые перья стрел
Детские:
детские приключения
8.58
рейтинг книги
Некромант
4. Петр Синельников
Фантастика:
боевая фантастика
6.20
рейтинг книги
На границе империй. Том 10. Часть 5
23. Фортуна дама переменчивая
Фантастика:
космическая фантастика
попаданцы
5.00
рейтинг книги
Барон. Книга вторая
6. Ученик
Фантастика:
фэнтези
попаданцы
5.40
рейтинг книги
Эфемер
7. Стеллар
Фантастика:
боевая фантастика
рпг
7.23
рейтинг книги
Майами
Детективы:
триллеры
6.40
рейтинг книги
Чужак
1. Ушедший Род
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Старая школа рул
1. Второгодка
Фантастика:
альтернативная история
6.00
рейтинг книги
Требую развода! Что значит- вы отказываетесь?
Любовные романы:
любовно-фантастические романы
5.00