Linux программирование в примерах - Арнольд Роббинс
Шрифт:
Интервал:
Закладка:
«Будь готов»
- Бойскауты -Ошибки могут возникнуть в любое время. Диски могут заполниться, пользователи могут ввести неверные данные, сетевой сервер, с которого осуществляется чтение, может отказать, сеть может выйти из строя и т.д. Важно всегда проверять успешность завершения каждой операции.
Основные системные вызовы Linux почти всегда возвращают при ошибке -1 и 0 или положительное значение при успехе. Это дает возможность узнать, была операция успешной или нет:
int result;
result = some_system_call(param1, param2);
if (result < 0) {
/* ошибка, что-нибудь сделать */
} else
/* все нормально, продолжить */
Знания того, что произошла ошибка, недостаточно. Нужно знать, какая произошла ошибка. Для этого у каждого процесса есть предопределенная переменная с именем errno. Всякий раз, когда системный вызов завершается ошибкой, errno устанавливается в один из набора предопределенных значений ошибок errno и предопределенные значения ошибок определены в файле заголовка <errno.h>.
#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) для локальной системы.