Книга: Программирование для Linux. Профессиональный подход

Листинг 11.7. (issue.c) Серверный модуль, отображающий информацию о дистрибутиве Linux

Листинг 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"
 "  <p>Error: Could not open /etc/issue.</p>n"
 " </body>n"
 "</html>n";
/* Сообщение об ошибке. */
static char* error_message =
 "Error reading /etc/issue.";
void module_generate(int fd) {
 int input_fd;
 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 будут не нужны.

Оглавление книги


Генерация: 1.250. Запросов К БД/Cache: 3 / 1
поделиться
Вверх Вниз