Читаем Linux API. Исчерпывающее руководство полностью

команды 'gcc — Wall', жалующиеся, что "control reaches end of non-void

function", то есть что управление достигло конца функции, которая

должна вернуть значение, если мы используем следующие функции для

прекращения выполнения main() или какой-нибудь другой функции,

которая должна вернуть значение определенного типа (не void) */

#define NORETURN __attribute__ ((__noreturn__))

#else

#define NORETURN

#endif

void errExit(const char *format…) NORETURN;

void err_exit(const char *format…) NORETURN;

void errExitEN(int errnum, const char *format…) NORETURN;

void fatal(const char *format…) NORETURN;

void usageErr(const char *format…) NORETURN;

void cmdLineErr(const char *format…) NORETURN;

#endif

lib/error_functions.h

Для определения типа ошибок системных вызовов и библиотечных функций используются функции errMsg(), errExit(), err_exit() и errExitEN().

#include "tlpi_hdr.h"

void errMsg(const char *format…);

void errExit(const char *format…);

void err_exit(const char *format…);

void errExitEN(int errnum, const char *format…);

Функция errMsg() выводит сообщение на стандартное устройство вывода ошибки. Ее список аргументов совпадает со списком для функции printf(), за исключением того, что в строку вывода автоматически добавляется символ конца строки. Функция errMsg() выводит текст ошибки, соответствующий текущему значению переменной errno. Этот текст состоит из названия ошибки, например EPERM, дополненного описанием ошибки в том виде, в котором его возвращает функция strerror(), а затем следует вывод, отформатированный согласно переданным агрументам.

По своему действию функция errExit() похожа на errMsg(), но она также прекращает выполнение программы, либо вызвав функцию exit(), либо, если переменная среды EF_DUMPCORE содержит непустое строковое значение, вызвав функцию abort(), чтобы создать файл дампа ядра для его использования отладчиком. (Файлы дампа ядра будут рассмотрены в разделе 22.1.)

Функция err_exit() похожа на errExit(), но имеет два отличия:

• не сбрасывает стандартный вывод перед выводом в него сообщения об ошибке;

• завершает процесс путем вызова _exit(), а не exit(). Это приводит к тому, что процесс завершается без сброса буферов stdio или вызова обработчиков выхода.

Подробности этих различий в работе err_exit() станут понятнее при изучении главы 25, где рассматривается разница между _exit() и exit(), а также обработка буферов stdio и обработчики выхода в дочернем процессе, созданном с помощью fork(). А пока мы просто возьмем на заметку, что функция err_exit() будет особенно полезна при написании нами библиотечной функции, создающей дочерний процесс, который следует завершить по причине возникновения ошибки. Это завершение должно произойти без сброса дочерней копии родительских буферов stdio (то есть буферов вызывающего процесса) и без вызова обработчиков выхода, созданных родительским процессом.

Функция errExitEN() представляет собой практически то же самое, что и errExit(), за исключением того, что вместо сообщения об ошибке, характерного текущему значению errno, она выводит текст, соответствующий номеру ошибки (отсюда и суффикс EN), заданному в аргументе errnum.

В основном функция errExitEN() применяется в программах, использующих API потоков стандарта POSIX. В отличие от традиционных системных вызовов UNIX, возвращающих при возникновении ошибки –1, функции потоков стандарта POSIX позволяют определить тип ошибки по ее номеру, возвращенному в качестве результата их выполнения (то есть в errno, как правило, помещается положительный номер типа). (В случае успеха функции потоков стандарта POSIX возвращают 0.)

Определить типы ошибок из функции потоков стандарта POSIX можно с помощью следующего кода:

errno = pthread_create(&thread, NULL, func, &arg);

if (errno!= 0)

errExit("pthread_create");

Но такой подход неэффективен, поскольку в программе, выполняемой в нескольких потоках, errno определяется в качестве макроса. Этот макрос расширяется в вызов функции, возвращающий левостороннее выражение (lvalue). Соответственно, каждое использование errno приводит к вызову функции. Функция errExitEN() позволяет создавать более эффективный эквивалент показанного выше кода:

int s;

s = pthread_create(&thread, NULL, func, &arg);

if (s!= 0)

errExitEN(s, "pthread_create");

Согласно терминологии языка C левостороннее выражение (lvalue) — это выражение, ссылающееся на область хранилища3. Наиболее характерным его примером является идентификатор для переменной. Некоторые операторы также выдают такие выражения. Например, если p является указателем на область хранилища, то *p является левосторонним выражением. Согласно API потоков стандарта POSIX, errno переопределяется в функцию, возвращающую указатель на область хранилища, относящуюся к отдельному потоку (см. раздел 31.3).

Для определения других типов ошибок используются функции fatal(), usageErr() и cmdLineErr().

#include "tlpi_hdr.h"

void fatal(const char *format…);

void usageErr(const char *format…);

Перейти на страницу:

Похожие книги

1С: Бухгалтерия 8 с нуля
1С: Бухгалтерия 8 с нуля

Книга содержит полное описание приемов и методов работы с программой 1С:Бухгалтерия 8. Рассматривается автоматизация всех основных участков бухгалтерии: учет наличных и безналичных денежных средств, основных средств и НМА, прихода и расхода товарно-материальных ценностей, зарплаты, производства. Описано, как вводить исходные данные, заполнять справочники и каталоги, работать с первичными документами, проводить их по учету, формировать разнообразные отчеты, выводить данные на печать, настраивать программу и использовать ее сервисные функции. Каждый урок содержит подробное описание рассматриваемой темы с детальным разбором и иллюстрированием всех этапов.Для широкого круга пользователей.

Алексей Анатольевич Гладкий

Программирование, программы, базы данных / Программное обеспечение / Бухучет и аудит / Финансы и бизнес / Книги по IT / Словари и Энциклопедии
1С: Управление торговлей 8.2
1С: Управление торговлей 8.2

Современные торговые предприятия предлагают своим клиентам широчайший ассортимент товаров, который исчисляется тысячами и десятками тысяч наименований. Причем многие позиции могут реализовываться на разных условиях: предоплата, отсрочка платежи, скидка, наценка, объем партии, и т.д. Клиенты зачастую делятся на категории – VIP-клиент, обычный клиент, постоянный клиент, мелкооптовый клиент, и т.д. Товарные позиции могут комплектоваться и разукомплектовываться, многие товары подлежат обязательной сертификации и гигиеническим исследованиям, некондиционные позиции необходимо списывать, на складах периодически должна проводиться инвентаризация, каждая компания должна иметь свою маркетинговую политику и т.д., вообщем – современное торговое предприятие представляет живой организм, находящийся в постоянном движении.Очевидно, что вся эта кипучая деятельность требует автоматизации. Для решения этой задачи существуют специальные программные средства, и в этой книге мы познакомим вам с самым популярным продуктом, предназначенным для автоматизации деятельности торгового предприятия – «1С Управление торговлей», которое реализовано на новейшей технологической платформе версии 1С 8.2.

Алексей Анатольевич Гладкий

Финансы / Программирование, программы, базы данных