Чтение онлайн

на главную - закладки

Жанры

Программирование для 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.50
рейтинг книги
Моя на одну ночь

Черный Маг Императора 8

Герда Александр
8. Черный маг императора
Фантастика:
юмористическое фэнтези
попаданцы
аниме
5.00
рейтинг книги
Черный Маг Императора 8

Измена. Отбор для предателя

Лаврова Алиса
1. Отбор для предателя
Фантастика:
фэнтези
5.00
рейтинг книги
Измена. Отбор для предателя

Кодекс Крови. Книга II

Борзых М.
2. РОС: Кодекс Крови
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Кодекс Крови. Книга II

Шаг в бездну

Муравьёв Константин Николаевич
3. Перешагнуть пропасть
Фантастика:
фэнтези
космическая фантастика
7.89
рейтинг книги
Шаг в бездну

Часовая битва

Щерба Наталья Васильевна
6. Часодеи
Детские:
детская фантастика
9.38
рейтинг книги
Часовая битва

Вечная Война. Книга II

Винокуров Юрий
2. Вечная война.
Фантастика:
юмористическая фантастика
космическая фантастика
8.37
рейтинг книги
Вечная Война. Книга II

Хроники странного королевства. Вторжение. (Дилогия)

Панкеева Оксана Петровна
110. В одном томе
Фантастика:
фэнтези
9.38
рейтинг книги
Хроники странного королевства. Вторжение. (Дилогия)

Часовой ключ

Щерба Наталья Васильевна
1. Часодеи
Фантастика:
фэнтези
9.36
рейтинг книги
Часовой ключ

Инвестиго, из медика в маги

Рэд Илья
1. Инвестиго
Фантастика:
фэнтези
городское фэнтези
попаданцы
5.00
рейтинг книги
Инвестиго, из медика в маги

Кротовский, может, хватит?

Парсиев Дмитрий
3. РОС: Изнанка Империи
Фантастика:
попаданцы
альтернативная история
аниме
7.50
рейтинг книги
Кротовский, может, хватит?

Драконий подарок

Суббота Светлана
1. Королевская академия Драко
Любовные романы:
любовно-фантастические романы
7.30
рейтинг книги
Драконий подарок

Очешуеть! Я - жена дракона?!

Амеличева Елена
Фантастика:
юмористическая фантастика
5.43
рейтинг книги
Очешуеть! Я - жена дракона?!

Идеальный мир для Лекаря 9

Сапфир Олег
9. Лекарь
Фантастика:
боевая фантастика
юмористическое фэнтези
6.00
рейтинг книги
Идеальный мир для Лекаря 9