ERRNO(3)

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

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

ОПИСАНИЕ
В заголовочном файле <errno.h> определяется целочисленная переменная errno, которая используется системными вызовами и некоторыми библиотечными функциями при ошибках для указания того, что именно произошло.

  errno
Значение errno имеет смысл только тогда, когда вызов возвратил ошибку (а именно: -1 — для большинства системных вызовов; NULL — для большинства библиотечных функций); при успешном выполнении функции также могут менять значение errno. Системные вызовы и библиотечные функции никогда не присваивают errno значение нуля.

Некоторые системные вызовы или библиотечные функции (например, getpriority(2)), при успешном выполнении возвращают -1. В этих случаях успешность выполнения можно отличить от ошибки присвоив errno значение нуля перед вызовом, и затем, если вызов вернул состояние, которое может указывать на ошибку, проверить, равно ли errno ненулевому значению.

Переменная errno определена в стандарте ISO C как изменяемое lvalue int и не объявляемая явно; errno может быть и макросом. Переменная errno является локальным значением нити; её изменение в одной нити не влияет на её значение в другой нити.

  Номера и имена ошибок
Все положительные числа считаются допустимыми номерами ошибок. В заголовочном файле <errno.h> определены символические имена для каждого номера возможной ошибки, который может появиться в errno.

Всем названиям ошибок, определённым в POSIX.1, должны соответствовать разные значения, за исключением EAGAIN и EWOULDBLOCK, которые могут быть одинаковыми.

В разных системах UNIX символическим именам ошибок назначены разные номера, и это верно даже в Linux для разных архитектур. Поэтому числовые значение не указаны в представленном далее списке имён ошибок. Для преобразования этих имён в текстовые сообщения об ошибках можно использовать функции perror(3) и strerror(3).

В любой системе Linux можно получить список всех символических имён ошибок и соответствующие им номера с помощью команды errno(1):

    $ errno -l
    EPERM 1 Операция не позволена
    ENOENT 2 Нет такого файла или каталога
    ESRCH 3 Нет такого процесса
    EINTR 4 Прерван системный вызов
    EIO 5 Ошибка ввода/вывода
    ...

Команду errno(1) также можно использовать для поиска ошибок по имени или номеру, а также по строке, входящей в описание ошибки:

    $ errno 2
    ENOENT 2 Нет такого файла или каталога
    $ errno ESRCH
    ESRCH 3 Нет такого процесса
    $ errno -s permission
    EACCES 13 Отказано в доступе

  Список имён ошибок
В представленном далее списки символических имён ошибок у некоторых есть некоторые примечания:

*   POSIX.1-2001: Имя определено в POSIX.1-2001, а также, если не указано обратного, в новых версиях POSIX.1.

*   POSIX.1-2008: Имя определено в POSIX.1-2008, но отсутствует в более старых версиях POSIX.1.

*   C99: Имя определено в C99. Ниже представлен список символических имён ошибок, определённых в Linux:

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

EDEADLOCK
    Синоним EDEADLK.

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

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

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

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

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

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

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

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

EHWPOISON
    В странице памяти аппаратная ошибка.

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

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

    Этот текст взят из описания ошибки glibc; в POSIX.1 эта ошибка звучит как «Недопустимая последовательность байт».

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

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

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

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

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

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

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

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

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

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

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

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

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

EL3RST
    Уровень 3 сброшен.

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

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

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

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

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

ELNRANGE
    Число ссылок вне допустимого диапазона.

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

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

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

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

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

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

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

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

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

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

ENFILE
    Слишком много открытых файлов в системе (POSIX.1-2001). В Linux это, вероятно, результат достижения ограничения /proc/sys/fs/file-max (смотрите proc(5)).

ENOANO
    Не anode.

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

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

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

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

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

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

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

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

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

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

ENOMEM
    Недостаточно места/невозможно выделить память (POSIX.1-2001).

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

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

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

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

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

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

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

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

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

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

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

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

ENOTRECOVERABLE
    Состояние нельзя восстановить (POSIX.1-2008).

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

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

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

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

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

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

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

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

EOWNERDEAD
    Владелец умер (POSIX.1-2008).

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

EPFNOSUPPORT
    Семейство протоколов не поддерживается.

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

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

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

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

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

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

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

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

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

ERFKILL
    Операция не позволяется из-за RF-kill.

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

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

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

ESOCKTNOSUPPORT
    Тип сокета не поддерживается.

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

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

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

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

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

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

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

ETOOMANYREFS
    Слишком много ссылок: невозможно объединить.

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

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

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

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

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

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

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.h> отсутствовал или не объявлял errno, поэтому это нужно было делать вручную (например, extern int errno). Не делайте этого. Это давно уже не нужно, и вызовет проблемы с современными версиями библиотеки C.

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