Марк Митчелл - Программирование для Linux. Профессиональный подход

Скачивание начинается... Если скачивание не началось автоматически, пожалуйста нажмите на эту ссылку.
Жалоба
Напишите нам, и мы в срочном порядке примем меры.
Описание книги "Программирование для Linux. Профессиональный подход"
Описание и краткое содержание "Программирование для Linux. Профессиональный подход" читать бесплатно онлайн.
Данная книга в основном посвящена программированию в среде GNU/Linux. Авторы применяют обучающий подход, последовательно излагая самые важные концепции и методики использования расширенных возможностей системы GNU/Linux в прикладных программах. Читатели научатся писать программы, к интерфейсу которых привыкли пользователи Linux; освоят такие технологии, как многозадачность, многопотоковое программирование, межзадачное взаимодействие и взаимодействие с аппаратными устройствами; смогут улучшить свои программы, сделав их быстрее, надежнее и безопаснее; поймут особенности системы GNU/Linux, ее ограничения, дополнительные возможности и специфические соглашения.
Книга предназначена для программистов, уже знакомых с языком С и имеющих базовый опыт работы в GNU/Linux.
return ptr;
}
char* xstrdup(const char* s) {
char* copy = strdup(s);
/* Аварийное завершение, если выделить память не удалось. */
if (сору == NULL)
abort();
else
return copy;
}
void system_error(const char* operation) {
/* Вывод сообщения об ошибке на основании значения
переменной errno. */
error(operation, strerror(errno));
}
void error(const char* cause, const char* message) {
/* Запись сообщения об ошибке в поток stderr. */
fprintf(stderr, "%s: error: (%s) %s\n", program_name,
cause, message);
/* Завершение программы */
exit(1);
}
char* get_self_executable_directory() {
int rval;
char link_target[1024];
char* last_slash;
size_t result_length;
char* result;
/* Чтение содержимого символической ссылки /proc/self/exe. */
rval =
readlink("/proc/self/exe", link_target,
sizeof(link_target));
if (rval == -1)
/* Функция readlink() завершилась неудачей, поэтому выходим
из программы. */
abort();
else
/* Запись нулевого символа в конец строки. */
link_target[rval] = '\0';
/* Удаление имени файла,
чтобы осталось только имя каталога. */
last_slash = strrchr(link_target, '/');
if (last_slash == NULL || last_slash == link_target)
/* Формат имени некорректен. */
abort();
/* Выделение буфера для результирующей строки. */
result_length = last_slash - link_target;
result = (char*)xmalloc(result_length + 1);
/* Копирование результата. */
strncpy(result, link_target, result_length);
result[result_length] = '\0';
return result;
}
Приведенные здесь функции можно использовать в самых разных программах.
■ Функции xmalloc(), xrealloc() и xstrdup() являются расширенными версиями стандартных функций malloc(), realloc() и strdup(), в которые дополнительно включен код проверки ошибок. В отличие от стандартных функций, которые возвращают пустой указатель в случае ошибки, наши функции немедленно завершают работу программы, если в системе недостаточно памяти.
Раннее обнаружение нехватки памяти — хорошая идея. Если этого не делать, пустые указатели будут появляться в самых неожиданных местах программы. Ситуации, связанные с нехваткой памяти, непросто воспроизвести, поэтому их отладка будет затруднена. Ошибки выделения памяти обычно имеют катастрофические последствия для программы, так что аварийное ее завершение — вполне приемлемый вариант реакции.
■ Функция error() сообщает о фатальной ошибке, произошедшей в программе. При этом в поток stderr записывается сообщение об ошибке, и работа программы завершается. Для ошибок, произошедших в системных вызовах или библиотечных функциях, предназначена функция system_error(), которая генерирует сообщение об ошибке на основании значения переменной errno (см. раздел 2.2.3, "Коды ошибок системных вызовов").
■ Функция get_self_executable_directory() определяет каталог, в котором содержится исполняемый файл текущего процесса. Это позволяет программе находить свои внешние компоненты. Функция проверяет содержимое символической ссылки /proc/self/exe (см. раздет 7.2.1, "Файл /proc/self).
В файле common.c определены также две полезные глобальные переменные.
■ Переменная program_name содержит имя выполняемой программы, указанное в списке аргументов командной строки (см. раздел 2.1.1, "Список аргументов").
■ Переменная verbose не равна нулю, если программа работает в режиме выдачи развернутых сообщений. В таком случае многие компоненты будут записывать в поток stdout сообщения о ходе выполнения задачи.
11.2.2. Загрузка серверных модулей
В файле module.c (листинг 11.3) содержится реализация динамически загружаемых серверных модулей. Загруженному модулю соответствует структура типа server_module, который определен в файле server.h.
Листинг 11.3. (module.c) Загрузка и выгрузка серверных модулей#include <dlfcn.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "server.h"
char* module_dir;
struct server_module* module_open(const char* module_name) {
char* module_path;
void* handle;
void (*module_generate)(int);
struct server_module* module;
/* Формирование путевого имени библиотеки, в которой содержится
загружаемый модуль. */
module_path =
(char*)xmalloc(strlen(module_dir) +
strlen(module_name) + 2);
sprintf(module_path, "%s/%s", module_dir, module_name);
/* Попытка открыть файл MODULE_PATH как совместно используемую
библиотеку. */
handle = dlopen(module_path, RTLD_NOW);
free (module_path);
if (handle == NULL) {
/* Ошибка: либо путь не существует, либо файл не является
совместно используемой библиотекой. */
return NULL;
}
/* Чтение константы module_generate из библиотеки. */
module_generatе =
(void(*)int))dlsym(handle,
"module_generate");
/* Проверяем, найдена ли константа. */
if (module_generate == NULL) {
/* Константа отсутствует в библиотеке. Очевидно, файл не
является серверным модулем. */
dlclose(handle);
return NULL;
}
/* Выделение и инициализация объекта server_module. */
module =
(struct server_module*)xmalloc
(sizeof (struct server_module));
module->handle = handle;
module->name = xstrdup(module_name);
module->generate_function = module_generate;
/* Успешное завершение функции. */
return module;
}
void module_close(struct server_module* module) {
/* Закрытие библиотеки. */
dlclose(module->handle);
/* Удаление строки с именем модуля. */
free((char*)module->name);
/* Удаление объекта module. */
free(module);
}
Каждый модуль содержится в файле совместно используемой библиотеки (см. раздел 2.3.2, "Совместно используемые библиотеки") и должен экспортировать функцию module_generate(). Эта функция генерирует HTML-код Web-страницы и записывает его в сокет, дескриптор которого передан ей в качестве аргумента.
В файле module.c определены две функции.
■ Функция module_open() пытается загрузить серверный модуль с указанным именем. Файл модуля имеет расширение .so, так как это совместно используемая библиотека. Функция открывает библиотеку с помощью функции dlopen() и ищет в библиотеке константу module_generate посредством функции dlsym() (описаны в разделе 2.3.6, "Динамическая загрузка и выгрузка"). Если библиотеку не удалось открыть или в ней не обнаружена экспортируемая константа module_generate, возвращается значение NULL. В противном случае выделяется и возвращается объект module.
■ Функция module_close() закрывает совместно используемую библиотеку, соответствующую указанному модулю, и удаляет объект module.
В файле module.c определена также глобальная переменная module_dir. В ней записано имя каталога, в котором функция module_open() будет искать совместно используемые библиотеки.
11.2.3. Сервер
Файл server.c (листинг 11.4) представляет собой реализацию простейшего HTTP-сервера.
Листинг 11.4. (server.c) Реализация HTTP-сервера#include <arpa/inet.h>
#include <assert.h>
#include <errno.h>
#include <netinet/in.h>
#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <unistd.h>
#include "server.h"
/* HTTP-ответ и заголовок, возвращаемые в случае
успешной обработки запроса. */
static char* ok_response =
"HTTP/1.0 100 OK\n"
"Content-type: text/html\n"
"\n";
/* HTTP-ответ, заголовок и тело страницы на случай
непонятного запроса. */
static char* bad_request_response =
"HTTP/1.0 400 Bad Reguest\n"
"Content-type: text/html\n"
"\n"
"<html>\n"
" <body>\n"
" <h1>Bad Request</h1>\n"
" <p>This server did not understand your request.</p>\n"
Подписывайтесь на наши страницы в социальных сетях.
Будьте в курсе последних книжных новинок, комментируйте, обсуждайте. Мы ждём Вас!
Похожие книги на "Программирование для Linux. Профессиональный подход"
Книги похожие на "Программирование для Linux. Профессиональный подход" читать онлайн или скачать бесплатно полные версии.
Мы рекомендуем Вам зарегистрироваться либо войти на сайт под своим именем.
Отзывы о "Марк Митчелл - Программирование для Linux. Профессиональный подход"
Отзывы читателей о книге "Программирование для Linux. Профессиональный подход", комментарии и мнения людей о произведении.