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

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

Жанры

Linux программирование в примерах

Роббинс Арнольд

Шрифт:

#include <errno.h> /* ISO С */

extern int errno;

Хотя сама

errno
может быть макросом, который действует подобно переменной
int
 — она не обязательно является действительной целой переменной. В частности, в многопоточном окружении у каждого потока будет своя индивидуальная версия
errno
. Несмотря на это, практически для всех системных вызовов и функций в данной книге вы можете рассматривать
errno
как простую
int
.

4.3.1. Значения

errno

Стандарт POSIX 2001 определяет большое число возможных значений для errno. Многие из них относятся к сетям, IPC или другим специальным задачам. Справочная страница для каждого системного вызова описывает возможные значения

errno
, которые могут иметь место; поэтому вы можете написать код для проверки отдельных ошибок и соответствующим образом обработать их, если это нужно. Возможные значения определены через символические имена. Предусмотренные GLIBC значения перечислены в табл. 4.1.

Таблица 4.1. Значения GLIBC для

errno

Имя Значение
E2BIG
Слишком длинный список
аргументов
EACCESS
Доступ запрещен
EADDRINUSE
Адрес используется
EADDRNOTAVAIL
Адрес недоступен
EAFNOSUPPORT
Семейство адресов не поддерживается
EAGAIN
Ресурс недоступен, попытайтесь снова (может быть то же самое значение, что
EWOULDBLOCK
).
EALREADY
Соединение уже устанавливается
EBADF
Ошибочный дескриптор файла.
EBADMSG
Ошибочное сообщение.
EBUSY
Устройство или ресурс заняты
ECANCELED
Отмена операции.
ECHILD
Нет порожденного процесса.
ECONNABORTED
Соединение прервано
ECONNFRFUSED
Соединение отклонено
ECONNRESET
Восстановлено исходное состояние соединения.
EDEADLK
Возможен тупик (deadlock) в запросе ресурса.
EDESTADDRREQ
Требуется адрес назначения
EDOM
Математический аргумент выходит за область определения функции
EDQUOT
Зарезервировано.
EEXIST
Файл существует.
EFAULT
Ошибочный адрес.
EFBIG
Файл слишком большой.
EHOSTUNREACH
Хост недоступен.
EIDRM
Идентификатор удален
EILSEQ
Ошибочная последовательность байтов.
EINPROGRESS
Операция исполняется.
EINTR
Прерванная функция.
EINVAL
Недействительный аргумент.
EIO
Ошибка ввода/вывода.
EISCONN
Сокет (уже) соединен.
EISDIR
Это каталог.
ELOOP
Слишком много уровней символических ссылок.
EMFILE
Слишком много открытых файлов.
EMLINK
Слишком много ссылок.
EMSGSIZE
Сообщение слишком длинное.
EMULTIHOP
Зарезервировано.
ENAMETOOLONG
Имя файла слишком длинное
ENETDOWN
Сеть не работает
ENETRESET
Соединение прервано сетью
ENETUNREACH
Сеть недоступна.
ENFILE
В системе открыто слишком много файлов.
ENOBUFS
Буферное пространство недоступно.
ENODEV
Устройство отсутствует
ENOENT
Файл или каталог отсутствуют
ENOEXEC
Ошибочный формат исполняемого файла.
ENOLCK
Блокировка недоступна.
ENOLINK
Зарезервировано.
ENOMEM
Недостаточно памяти.
ENOMSG
Сообщение нужного типа отсутствует
ENOPROTOOPT
Протокол недоступен.
ENOSPC
Недостаточно памяти в устройстве.
ENOSYS
Функция не поддерживается.
ENOTCONN
Сокет не соединен.
ENOTDIR
Это не каталог
ENOTEMPTY
Каталог не пустой.
ENOTSOCK
Это не сокет
ENOTSUP
Не
поддерживается
ENOTTY
Неподходящая операция управления вводом/выводом
ENXIO
Нет такого устройства или адреса.
EOPNOTSUPP
Операция сокета не поддерживается
EOVERFLOW
Слишком большое значение для типа данных
EPERM
Операция не разрешена
EPIPE
Канал (pipe) разрушен
EPROTO
Ошибка протокола.
EPROTONOSUPPORT
Протокол не поддерживается
EPROTOTYPE
Ошибочный тип протокола для сокета
ERANGE
Результат слишком большой
EROFS
Файловая система только для чтения
ESPIPE
Недействительный поиск
ESRCH
Нет такого процесса
ESTALE
Зарезервировано
ETIMEDOUT
Тайм-аут соединения истек
ETXTBSY
Текстовый файл занят
EWOULDBLOCK
Блокирующая операция (может быть то же значение, что и для
EAGAIN
)
EXDEV
Ссылка через устройство (cross-device link)

Многие системы предоставляют также другие значения ошибок, а в более старых системах может не быть всех перечисленных значений ошибок. Полный список следует проверить с помощью справочных страниц intro(2) и errno(2) для локальной системы.

ЗАМЕЧАНИЕ.

errno
следует проверять лишь после того, как возникла ошибка и до того, как сделаны дальнейшие системные вызовы. Начальное значение той переменной 0. Однако, в промежутках между ошибками ничто не изменяет ее значения, это означает, что успешный системный вызов не восстанавливает значение 0. Конечно, вы можете вручную установить ее в 0 в самом начале или когда захотите, однако это делается редко.

Сначала мы используем

errno
лишь для сообщений об ошибках. Для этого имеются две полезные функции. Первая —
perror
:

#include <stdio.h> /* ISO С */

void perror(const char *s);

Функция

perror
выводит предоставленную программой строку, за которой следует двоеточие, а затем строка, описывающая значение
errno
:

if (some_system_call(param1, param2) < 0) {

 perror("system call failed");

 return 1;

}

Мы предпочитаем функцию

strerror
, которая принимает параметр со значением ошибки и возвращает указатель на строку с описанием ошибки:

#include <string.h> /* ISO С */

char *strerror(int errnum);

strerror
предоставляет для сообщений об ошибках максимальную гибкость, поскольку
fprintf
дает возможность выводить ошибки любым нужным нам способом, наподобие этого.

if (some_system_call(param1, param2) < 0) {

 fprintf(stderr, "%s: %d, %d: some_system_call failed: %s\n",

argv[0], param1, param2, strerror(errno));

 return 1;

}

По всей книге вы увидите множество примеров использования обеих функций.

4.3.2. Стиль сообщения об ошибках

Для использования в сообщениях об ошибках С предоставляет несколько специальных макросов. Наиболее широкоупотребительными являются

__FILE__
и
__LINE__
, которые разворачиваются в имя исходного файла и номер текущей строки в этом файле. В С они были доступны с самого начала. C99 определяет дополнительный предопределенный идентификатор,
__func__
, который представляет имя текущей функции в виде символьной строки. Макросы используются следующим образом:

if (some_system_call(param1, param2) < 0) {

 fprintf(stderr, "%s: %s (%s %d): some_system_call(%d, %d) failed: %s\n",

argv[0], __func__, __FILE__, __LINE__,

param1, param2, strerror(errno));

 return 1;

}

Здесь сообщение об ошибке включает не только имя программы, но также и имя функции, имя исходного файла и номер строки. Полный список идентификаторов, полезных для диагностики, приведен в табл. 4.2.

Таблица 4.2. Диагностические идентификаторы C99

Идентификатор Версия С Значение
__DATE__
C89 Дата компиляции в виде «
Mmm nn yyyy
»
__FILE_
Оригинальная Имя исходного файла в виде «
program.c
»
__LINE__
Оригинальная Номер строки исходного файла в виде 42
__TIME__
C89 Время компиляции в виде «
hh:mm:ss
»
__func__
C99 Имя текущей функции, как если бы было объявлено
const char __func__[] = "name"

Использование

__FILE__
и
__LINE__
было вполне обычно для ранних дней Unix, когда у большинства людей были исходные коды и они могли находить ошибки и устранять их. По мере того, как системы Unix становились все более коммерческими, использование этих идентификаторов постепенно уменьшалось, поскольку знание положения в исходном коде дает немного пользы, когда имеется лишь двоичный исполняемый файл.

Сегодня, хотя системы GNU/Linux поставляются с исходными кодами, указанный исходный код часто не устанавливается по умолчанию. Поэтому использование этих идентификаторов для сообщений об ошибках не представляет дополнительной ценности. GNU Coding Standards даже не упоминает их.

Поделиться:
Популярные книги

Газлайтер. Том 10

Володин Григорий
10. История Телепата
Фантастика:
боевая фантастика
5.00
рейтинг книги
Газлайтер. Том 10

На границе империй. Том 7. Часть 2

INDIGO
8. Фортуна дама переменчивая
Фантастика:
космическая фантастика
попаданцы
6.13
рейтинг книги
На границе империй. Том 7. Часть 2

Звездная Кровь. Изгой

Елисеев Алексей Станиславович
1. Звездная Кровь. Изгой
Фантастика:
боевая фантастика
попаданцы
рпг
5.00
рейтинг книги
Звездная Кровь. Изгой

Хозяин Теней 4

Петров Максим Николаевич
4. Безбожник
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Хозяин Теней 4

Картофельное счастье попаданки

Иконникова Ольга
Фантастика:
фэнтези
5.00
рейтинг книги
Картофельное счастье попаданки

Экзорцист: Проклятый металл. Жнец. Мор. Осквернитель

Корнев Павел Николаевич
Фантастика:
фэнтези
героическая фантастика
5.50
рейтинг книги
Экзорцист: Проклятый металл. Жнец. Мор. Осквернитель

Доктора вызывали? или Трудовые будни попаданки

Марей Соня
Фантастика:
юмористическая фантастика
попаданцы
5.00
рейтинг книги
Доктора вызывали? или Трудовые будни попаданки

Метатель

Тарасов Ник
1. Метатель
Фантастика:
боевая фантастика
попаданцы
рпг
фэнтези
фантастика: прочее
постапокалипсис
5.00
рейтинг книги
Метатель

Моя на одну ночь

Тоцка Тала
Любовные романы:
современные любовные романы
короткие любовные романы
5.50
рейтинг книги
Моя на одну ночь

Чехов. Книга 2

Гоблин (MeXXanik)
2. Адвокат Чехов
Фантастика:
фэнтези
альтернативная история
аниме
5.00
рейтинг книги
Чехов. Книга 2

Хозяин Теней 2

Петров Максим Николаевич
2. Безбожник
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Хозяин Теней 2

Сумеречный стрелок 7

Карелин Сергей Витальевич
7. Сумеречный стрелок
Фантастика:
городское фэнтези
попаданцы
аниме
5.00
рейтинг книги
Сумеречный стрелок 7

Жизнь под чужим солнцем

Михалкова Елена Ивановна
Детективы:
прочие детективы
9.10
рейтинг книги
Жизнь под чужим солнцем

Красноармеец

Поселягин Владимир Геннадьевич
1. Красноармеец
Фантастика:
боевая фантастика
попаданцы
4.60
рейтинг книги
Красноармеец