ERRNO(3)

ИМЯ
errno - код последней ошибки

ОБЗОР
#include <errno.h>

ОПИСАНИЕ
В заголовочном файле <errno.h> определяется целочисленная переменная errno, которая используется системными вызовами и некоторыми библиотечными функциями при ошибках для указания того, что именно произошло. Её значение имеет смысл только тогда, когда вызов возвратил ошибку (т.е., -1 для большинства системных вызовов или NULL — для большинства библиотечных функций); при успешном выполнении функции также могут менять значение errno. Допускаемые номера ошибок не равны нулю; значение errno никогда не устанавливается в ноль какими-либо системными вызовами или библиотечными функциями. Некоторые системные вызовы или библиотечные функции (например, getpriority(2)), при успешном выполнении возвращают -1. В этих случаях успешность выполнения можно отличить от ошибки присвоив errno значение нуля перед вызовом, и затем, если вызов вернул состояние, которое может указывать на ошибку, проверить, равно ли errno ненулевому значению. Переменная errno определена в стандарте ISO C как изменяемое lvalue int и не объявляемая явно; errno может быть и макросом. Переменная errno является локальным значением нити; её изменение в одной нити не влияет на её значение в другой нити. Всем названиям ошибок, определённым в POSIX.1, должны соответствовать разные значения, за исключением EAGAIN и EWOULDBLOCK, которые могут быть одинаковыми. Далее приведён список символических имён ошибок, определённых в Linux. Некоторые из них, отмеченные как POSIX.1, определены в POSIX.1-2001, а отмеченные как C99 — определены в C99.

E2BIG
    Слишком длинный список параметров (POSIX.1)

EACCES
    Доступ запрещён (POSIX.1)

EADDRINUSE
    Адрес уже используется (POSIX.1)

EADDRNOTAVAIL
    Адрес недоступен (POSIX.1)

EAFNOSUPPORT
    Семейство адресов не поддерживается (POSIX.1)

EAGAIN
    Ресурс временно недоступен (значение может быть равным EWOULDBLOCK) (POSIX.1)

EALREADY
    Соединение уже выполняется (POSIX.1)

EBADE
    Некорректный обмен

EBADF
    Неправильный дескриптор файла (POSIX.1)

EBADFD
    Некорректное состояние дескриптора файла

EBADMSG
    Неправильное сообщение (POSIX.1)

EBADR
    Неверный дескриптор запроса

EBADRQC
    Неверный код запроса

EBADSLT
    Некорректный слот

EBUSY
    Устройство или ресурс занято (POSIX.1)

ECANCELED
    Операция отменена (POSIX.1)

ECHILD
    Отсутствуют дочерние процессы (POSIX.1)

ECHRNG
    Номер канала вне диапазона

ECOMM
    Ошибка связи при отправке

ECONNABORTED
    Соединение было прервано (POSIX.1)

ECONNREFUSED
    В соединении отказано (POSIX.1)

ECONNRESET
    Соединение сброшено другой стороной (POSIX.1)

EDEADLK
    Предотвращена тупиковая ситуация при обращении к ресурсу (POSIX.1)

EDEADLOCK
    Синоним EDEADLK

EDESTADDRREQ
    Требуется указать адрес назначения (POSIX.1)

EDOM
    Математический аргумент вне области определения функции (POSIX.1, C99)

EDQUOT
    Превышена дисковая квота (POSIX.1)

EEXIST
    Файл существует (POSIX.1)

EFAULT
    Неправильный адрес (POSIX.1)

EFBIG
    Файл слишком велик (POSIX.1)

EHOSTDOWN
    Узел выключен

EHOSTUNREACH
    Узел недоступен (POSIX.1)

EIDRM
    Идентификатор удалён (POSIX.1)

EILSEQ
    Недопустимая последовательность байт (POSIX.1, C99)

EINPROGRESS
    Операция выполняется (POSIX.1)

EINTR
    Прерванный вызов функции (POSIX.1); смотрите signal(7).

EINVAL
    Неверный аргумент (POSIX.1)

EIO Ошибка ввода/вывода (POSIX.1)

EISCONN
    Сокет подключён (POSIX.1)

EISDIR
    Это каталог (POSIX.1)

EISNAM
    Является файлом именованного типа

EKEYEXPIRED
    Ключ с истёкшим сроком

EKEYREJECTED
    Ключ был отвергнут службой

EKEYREVOKED
    Ключ был отозван

EL2HLT
    Уровень 2 остановлен

EL2NSYNC
    Уровень 2 не синхронизирован

EL3HLT
    Уровень 3 остановлен

EL3RST
    Уровень 3 остановлен

ELIBACC
    Невозможно получить доступ к нужной общей библиотеке

ELIBBAD
    Обращение к повреждённой общей библиотеке

ELIBMAX
    Попытка компоновки с слишком большим количеством общих библиотек

ELIBSCN
    Секция lib в a.out повреждена

ELIBEXEC
    Невозможно непосредственно выполнить общую библиотеку

ELOOP
    Слишком много уровней символьных ссылок (POSIX.1)

EMEDIUMTYPE
    Неправильный тип носителя

EMFILE
    Слишком много открытых файлов (POSIX.1); обычно, это из-за превышения ограничения ресурса RLIMIT_NOFILE, описанного в getrlimit(2)

EMLINK
    Слишком много ссылок (POSIX.1)

EMSGSIZE
    Сообщение слишком длинное (POSIX.1)

EMULTIHOP
    Попытка Multihop (POSIX.1)

ENAMETOOLONG
    Название файла слишком длинное (POSIX.1)

ENETDOWN
    Сеть не работает (POSIX.1)

ENETRESET
    Соединение прервано из-за сети (POSIX.1)

ENETUNREACH
    Сеть недоступна (POSIX.1)

ENFILE
    Слишком много открытых файлов в системе (POSIX.1)

ENOBUFS
    Недостаточно буферного пространства (POSIX.1 (часть XSI STREAMS))

ENODATA
    Сообщение в голове очереди чтения STREAM отсутствует (POSIX.1)

ENODEV
    Нет такого устройства (POSIX.1)

ENOENT
    Нет такого файла или каталога (POSIX.1)

ENOEXEC
    Ошибка формата выполняемого файла (POSIX.1)

ENOKEY
    Требуемый ключ недоступен

ENOLCK
    Нет доступных блокировок (POSIX.1)

ENOLINK
    Соединение было разорвано (POSIX.1)

ENOMEDIUM
    Носитель не найден

ENOMEM
    Недостаточно места (POSIX.1)

ENOMSG
    Нет сообщения желаемого типа (POSIX.1)

ENONET
    Машина не в сети

ENOPKG
    Пакет не установлен

ENOPROTOOPT
    Протокол недоступен (POSIX.1)

ENOSPC
    На устройстве не осталось места (POSIX.1)

ENOSR
    Отсутствую ресурсы STREAM (POSIX.1 (часть XSI STREAMS))

ENOSTR
    Нет STREAM (POSIX.1 (часть XSI STREAMS))

ENOSYS
    Функция не реализована (POSIX.1)

ENOTBLK
    Требуется блочное устройство

ENOTCONN
    Сокет не подключён (POSIX.1)

ENOTDIR
    Не каталог (POSIX.1)

ENOTEMPTY
    Каталог не пуст (POSIX.1)

ENOTSOCK
    Не сокет (POSIX.1)

ENOTSUP
    Неподдерживаемая операция (POSIX.1)

ENOTTY
    Неподходящая операция управления вводом/выводом (POSIX.1)

ENOTUNIQ
    Имя не уникально в сети

ENXIO
    Нет такого устройства или адреса (POSIX.1)

EOPNOTSUPP
    Операция не поддерживается на сокете (POSIX.1)

    (ENOTSUP и EOPNOTSUPP в Linux имеют одинаковые значения, но согласно POSIX.1 значения этих ошибок должны различаться.)

EOVERFLOW
    Значение слишком велико для хранения в таком типе данных (POSIX.1)

EPERM
    Операция не позволена (POSIX.1)

EPFNOSUPPORT
    Неподдерживаемое семейство протоколов

EPIPE
    Обрыв канала (POSIX.1)

EPROTO
    Ошибка протокола (POSIX.1)

EPROTONOSUPPORT
    Протокол не поддерживается (POSIX.1)

EPROTOTYPE
    Неподдерживаемый тип протокола для сокета (POSIX.1)

ERANGE
    Результат слишком большой (POSIX.1, C99)

EREMCHG
    Удалённый адрес был изменён

EREMOTE
    Это удалённый объект

EREMOTEIO
    Ошибка удалённого ввода/вывода

ERESTART
    Прерванный системный вызов следует перезапустить

EROFS
    Файловая система, доступная только для чтения (POSIX.1)

ESHUTDOWN
    Невозможно отправить данные после выключения конечной точки передачи

ESPIPE
    Недопустимое перемещение (POSIX.1)

ESOCKTNOSUPPORT
    Неподдерживаемый тип сокета

ESRCH
    Нет такого процесса (POSIX.1)

ESTALE
    Неактуальный дескриптор файла (POSIX.1)

    Эта ошибка может возникать в NFS и других файловых системах

ESTRPIPE
    Ошибка потоков канала

ETIME
    Таймер истёк (POSIX.1 (часть XSI STREAMS))

    (в POSIX.1 описывается как «в ioctl(2) истекло время ожидания STREAM»)

ETIMEDOUT
    Время ожидания соединения истекло (POSIX.1)

ETXTBSY
    Текстовый файл занят (POSIX.1)

EUCLEAN
    Структуру необходимо почистить

EUNATCH
    Драйвер протокола не подсоединён

EUSERS
    Слишком много пользователей

EWOULDBLOCK
    Операция приведёт к блокировке (значение может быть равным EAGAIN) (POSIX.1)

EXDEV
    Некорректная ссылка (POSIX.1)

EXFULL
    Обмен полон

ЗАМЕЧАНИЯ
Распространённая ошибка:
if (somecall() == -1) {
    printf("somecall() failed\n");
    if (errno == ...) { ... }
}
Здесь errno может больше не иметь значение результата последнего вызова somecall() (т.е., значение может измениться из-за printf(3)). Если значение errno важно, то его нужно сохранять между библиотечными вызовами:
if (somecall() == -1) {
    int errsv = errno;
    printf("somecall() failed\n");
    if (errsv == ...) { ... }
}

Раньше в Си было распространена практика определения errno вручную (т.е., extern int errno), вместо включения файла <errno.h>. Не делайте этого. Это не будет работать с современными версиями библиотеки Си. Однако, на (очень) старых системах UNIX файл <errno.h> может отсутствовать и определение необходимо.

СМОТРИТЕ ТАКЖЕ
errno(1), err(3), error(3), perror(3), strerror(3)