4.3.1. Значения errno

We use cookies. Read the Privacy and Cookie Policy

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 ",

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

 return 1;

}

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