errno(3) код последней ошибки

ОБЗОР

#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); в Linux это, вероятно результат достижения ограничения /proc/sys/fs/file-max (смотрите proc(5)).
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> может отсутствовать и определение необходимо.