Марк Митчелл - Программирование для Linux. Профессиональный подход
- Название:Программирование для Linux. Профессиональный подход
- Автор:
- Жанр:
- Издательство:Вильямс
- Год:2002
- Город:Москва
- ISBN:5-8459-0243-6
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Марк Митчелл - Программирование для Linux. Профессиональный подход краткое содержание
Данная книга в основном посвящена программированию в среде GNU/Linux. Авторы применяют обучающий подход, последовательно излагая самые важные концепции и методики использования расширенных возможностей системы GNU/Linux в прикладных программах. Читатели научатся писать программы, к интерфейсу которых привыкли пользователи Linux; освоят такие технологии, как многозадачность, многопотоковое программирование, межзадачное взаимодействие и взаимодействие с аппаратными устройствами; смогут улучшить свои программы, сделав их быстрее, надежнее и безопаснее; поймут особенности системы GNU/Linux, ее ограничения, дополнительные возможности и специфические соглашения.
Книга предназначена для программистов, уже знакомых с языком С и имеющих базовый опыт работы в GNU/Linux.
Программирование для Linux. Профессиональный подход - читать онлайн бесплатно полную версию (весь текст целиком)
Интервал:
Закладка:
В ответ сервер сообщает результат обработки запроса. Типичный ответ таков: HTTP/1.0 200 OK
. Первый элемент — это версия протокола. В следующих двух элементах описан результат. В данном случае код 200 означает успешное выполнение запроса. Далее идут поля заголовка, который, оканчивается пустой строкой. После заголовка сервер может передать произвольные данные.
Обычно сервер возвращает HTML-код Web-страницы. В рассматриваемом примера в заголовке ответа будет указано следующее: Content-type: text/html
.
Спецификацию протокола HTTP можно получить по адресу http://www.w3.org/Protocols
.
11.2. Реализация
Во всех более-менее сложных C-программах требуется тщательно продумать организацию, чтобы сохранить модульность и обеспечить удобство сопровождения. Наша демонстрационная программа разделена на четыре главных исходных файла.
В каждом исходном файле экспортируются функции и переменные, используемые в других частях программы. Для простоты все они объявлены в одном файле заголовков: server.h
(листинг 11.1). Функции, применяемые в рамках только одного модуля, объявлены со спецификатором static
и не включены в файл server.h
.
#ifndef SERVER_H
#define SERVER_H
#include
#include
/*** Символические константы файла common.c. ********************/
/* Имя программы. */
extern const char* program_name;
/* Если не равна нулю, отображаются развернутые сообщения. */
extern int verbose;
/* Напоминает функцию malloc(), не прерывает работу программы,
если выделить память не удалось. */
extern void* xmalloc(size_t size);
/* Напоминает функцию realloc(), но прерывает работу программы,
если выделить память не удалось */
extern void* xrealloc(void* ptr, size_t size);
/* Напоминает функцию strdup(), но прерывает работу программы,
если выделить память не удалось. */
extern char* xstrdup(const char* s);
/* Выводит сообщение об ошибке заданного системного вызова
и завершает работу программы. */
extern void system_error(const char* operation);
/* Выводит сообщение об ошибке и завершает работу программы. */
extern void error(const char* cause, const char* message);
/* Возвращает имя каталога, содержащего исполняемый файл
программы. Поскольку возвращается указатель на область памяти,
вызывающая подпрограмма должна удалить ее с помощью
функции free(). В случае неудачи выполнение программы
завершается. */
extern char* get_self_executable_directory();
/*** Символические константы файла module.с *********************/
/* Экземпляр загруженного серверного модуля. */
struct server_module {
/* Дескриптор библиотеки, в которой находится модуль. */
void* handle;
/* Описательное имя модуля. */
const char* name;
/* Функция, генерирующая HTML-код для модуля. */
void (*generatе_function)(int);
};
/* Каталог, из которого загружаются модули. */
extern char* module_dir;
/* Функция, пытающаяся загрузить указанный серверный модуль.
Если модуль существует, возвращается структура
с его описанием, в противном случае возвращается NULL. */
extern struct server_module* module_open(const char* module_path);
/* Закрытие модуля и удаление объекта MODULE. */
extern void module_close(struct server_module* module);
/*** Символические константы файла server.c. ********************/
/* Запуск сервера по адресу LOCAL_ADDRESS и порту PORT. */
extern void server_run(struct in_addr local_address, uint16_t port);
#endif /* SERVER_H */
11.2.1. Общие функции
Файл common.c
(листинг 11.2) содержит функции общего назначения, используемые в разных частях программы.
#include
#include
#include
#include
#include
#include "server.h"
const char* program_name;
int verbose;
void* xmalloc(size_t size) {
void* ptr = malloc(size);
/* Аварийное завершение, если выделить память не удалось. */
if (ptr == NULL)
abort();
else
return ptr;
}
void* xrealloc(void* ptr, size_t size) {
ptr = realloc(ptr, size);
/* Аварийное завершение, если выделить память не удалось. */
if (ptr == NULL)
abort();
else
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()
, в которые дополнительно включен код проверки ошибок. В отличие от стандартных функций, которые возвращают пустой указатель в случае ошибки, наши функции немедленно завершают работу программы, если в системе недостаточно памяти.
Раннее обнаружение нехватки памяти — хорошая идея. Если этого не делать, пустые указатели будут появляться в самых неожиданных местах программы. Ситуации, связанные с нехваткой памяти, непросто воспроизвести, поэтому их отладка будет затруднена. Ошибки выделения памяти обычно имеют катастрофические последствия для программы, так что аварийное ее завершение — вполне приемлемый вариант реакции.
Читать дальшеИнтервал:
Закладка: