Errno список ошибок

# @see /usr/include/asm-generic/errno-base.h #ifndef _ASM_GENERIC_ERRNO_BASE_H #define _ASM_GENERIC_ERRNO_BASE_H #define EPERM 1 /* Operation not permitted */ #define ENOENT 2 /* No such file or directory */ #define ESRCH 3 /* No such process */ #define EINTR 4 /* Interrupted system call */ #define EIO 5 /* I/O error */ #define ENXIO 6 /* No such device or address */ #define E2BIG 7 /* Argument list too long */ #define ENOEXEC 8 /* Exec format error */ #define EBADF 9 /* Bad file number */ #define ECHILD 10 /* No child processes */ #define EAGAIN 11 /* Try again */ #define ENOMEM 12 /* Out of memory */ #define EACCES 13 /* Permission denied */ #define EFAULT 14 /* Bad address */ #define ENOTBLK 15 /* Block device required */ #define EBUSY 16 /* Device or resource busy */ #define EEXIST 17 /* File exists */ #define EXDEV 18 /* Cross-device link */ #define ENODEV 19 /* No such device */ #define ENOTDIR 20 /* Not a directory */ #define EISDIR 21 /* Is a directory */ #define EINVAL 22 /* Invalid argument */ #define ENFILE 23 /* File table overflow */ #define EMFILE 24 /* Too many open files */ #define ENOTTY 25 /* Not a typewriter */ #define ETXTBSY 26 /* Text file busy */ #define EFBIG 27 /* File too large */ #define ENOSPC 28 /* No space left on device */ #define ESPIPE 29 /* Illegal seek */ #define EROFS 30 /* Read-only file system */ #define EMLINK 31 /* Too many links */ #define EPIPE 32 /* Broken pipe */ #define EDOM 33 /* Math argument out of domain of func */ #define ERANGE 34 /* Math result not representable */ #endif # @see /usr/include/asm-generic/errno.h #ifndef _ASM_GENERIC_ERRNO_H #define _ASM_GENERIC_ERRNO_H #include <asm-generic/errno-base.h> #define EDEADLK 35 /* Resource deadlock would occur */ #define ENAMETOOLONG 36 /* File name too long */ #define ENOLCK 37 /* No record locks available */ #define ENOSYS 38 /* Function not implemented */ #define ENOTEMPTY 39 /* Directory not empty */ #define ELOOP 40 /* Too many symbolic links encountered */ #define EWOULDBLOCK EAGAIN /* Operation would block */ #define ENOMSG 42 /* No message of desired type */ #define EIDRM 43 /* Identifier removed */ #define ECHRNG 44 /* Channel number out of range */ #define EL2NSYNC 45 /* Level 2 not synchronized */ #define EL3HLT 46 /* Level 3 halted */ #define EL3RST 47 /* Level 3 reset */ #define ELNRNG 48 /* Link number out of range */ #define EUNATCH 49 /* Protocol driver not attached */ #define ENOCSI 50 /* No CSI structure available */ #define EL2HLT 51 /* Level 2 halted */ #define EBADE 52 /* Invalid exchange */ #define EBADR 53 /* Invalid request descriptor */ #define EXFULL 54 /* Exchange full */ #define ENOANO 55 /* No anode */ #define EBADRQC 56 /* Invalid request code */ #define EBADSLT 57 /* Invalid slot */ #define EDEADLOCK EDEADLK #define EBFONT 59 /* Bad font file format */ #define ENOSTR 60 /* Device not a stream */ #define ENODATA 61 /* No data available */ #define ETIME 62 /* Timer expired */ #define ENOSR 63 /* Out of streams resources */ #define ENONET 64 /* Machine is not on the network */ #define ENOPKG 65 /* Package not installed */ #define EREMOTE 66 /* Object is remote */ #define ENOLINK 67 /* Link has been severed */ #define EADV 68 /* Advertise error */ #define ESRMNT 69 /* Srmount error */ #define ECOMM 70 /* Communication error on send */ #define EPROTO 71 /* Protocol error */ #define EMULTIHOP 72 /* Multihop attempted */ #define EDOTDOT 73 /* RFS specific error */ #define EBADMSG 74 /* Not a data message */ #define EOVERFLOW 75 /* Value too large for defined data type */ #define ENOTUNIQ 76 /* Name not unique on network */ #define EBADFD 77 /* File descriptor in bad state */ #define EREMCHG 78 /* Remote address changed */ #define ELIBACC 79 /* Can not access a needed shared library */ #define ELIBBAD 80 /* Accessing a corrupted shared library */ #define ELIBSCN 81 /* .lib section in a.out corrupted */ #define ELIBMAX 82 /* Attempting to link in too many shared libraries */ #define ELIBEXEC 83 /* Cannot exec a shared library directly */ #define EILSEQ 84 /* Illegal byte sequence */ #define ERESTART 85 /* Interrupted system call should be restarted */ #define ESTRPIPE 86 /* Streams pipe error */ #define EUSERS 87 /* Too many users */ #define ENOTSOCK 88 /* Socket operation on non-socket */ #define EDESTADDRREQ 89 /* Destination address required */ #define EMSGSIZE 90 /* Message too long */ #define EPROTOTYPE 91 /* Protocol wrong type for socket */ #define ENOPROTOOPT 92 /* Protocol not available */ #define EPROTONOSUPPORT 93 /* Protocol not supported */ #define ESOCKTNOSUPPORT 94 /* Socket type not supported */ #define EOPNOTSUPP 95 /* Operation not supported on transport endpoint */ #define EPFNOSUPPORT 96 /* Protocol family not supported */ #define EAFNOSUPPORT 97 /* Address family not supported by protocol */ #define EADDRINUSE 98 /* Address already in use */ #define EADDRNOTAVAIL 99 /* Cannot assign requested address */ #define ENETDOWN 100 /* Network is down */ #define ENETUNREACH 101 /* Network is unreachable */ #define ENETRESET 102 /* Network dropped connection because of reset */ #define ECONNABORTED 103 /* Software caused connection abort */ #define ECONNRESET 104 /* Connection reset by peer */ #define ENOBUFS 105 /* No buffer space available */ #define EISCONN 106 /* Transport endpoint is already connected */ #define ENOTCONN 107 /* Transport endpoint is not connected */ #define ESHUTDOWN 108 /* Cannot send after transport endpoint shutdown */ #define ETOOMANYREFS 109 /* Too many references: cannot splice */ #define ETIMEDOUT 110 /* Connection timed out */ #define ECONNREFUSED 111 /* Connection refused */ #define EHOSTDOWN 112 /* Host is down */ #define EHOSTUNREACH 113 /* No route to host */ #define EALREADY 114 /* Operation already in progress */ #define EINPROGRESS 115 /* Operation now in progress */ #define ESTALE 116 /* Stale NFS file handle */ #define EUCLEAN 117 /* Structure needs cleaning */ #define ENOTNAM 118 /* Not a XENIX named type file */ #define ENAVAIL 119 /* No XENIX semaphores available */ #define EISNAM 120 /* Is a named type file */ #define EREMOTEIO 121 /* Remote I/O error */ #define EDQUOT 122 /* Quota exceeded */ #define ENOMEDIUM 123 /* No medium found */ #define EMEDIUMTYPE 124 /* Wrong medium type */ #define ECANCELED 125 /* Operation Canceled */ #define ENOKEY 126 /* Required key not available */ #define EKEYEXPIRED 127 /* Key has expired */ #define EKEYREVOKED 128 /* Key has been revoked */ #define EKEYREJECTED 129 /* Key was rejected by service */ /* for robust mutexes */ #define EOWNERDEAD 130 /* Owner died */ #define ENOTRECOVERABLE 131 /* State not recoverable */ #define ERFKILL 132 /* Operation not possible due to RF-kill */ #endif
errno(3) Library Functions Manual errno(3)

ИМЯ

errno — код
последней
ошибки

LIBRARY

Standard C library (libc, -lc)

СИНТАКСИС

#include <errno.h>

ОПИСАНИЕ

В
заголовочном
файле <errno.h>
определяется
целочисленная
переменная
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,
которые
могут быть
одинаковыми.
В Linux эти они
имеют
одинаковое
значение
на всех
архитектурах.

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

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

$ 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
The name is defined by POSIX.1-2001, and is defined in later POSIX.1
versions, unless otherwise indicated.
POSIX.1-2008
The name is defined in POSIX.1-2008, but was not present in earlier
POSIX.1 standards.
C99
The name is defined by C99.

Below is a list of the symbolic error names that are defined on
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. На
некоторых
архитектурах
(например, Linux
MIPS, PowerPC, SPARC), это
отдельный
код ошибки
«Ошибка
перекрёстной
блокировки
файла».
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
Невозможно
непосредственно
выполнить
общую
библиотеку.
ELNRNG
Число
ссылок вне
допустимого
диапазона.
ELOOP
Слишком
много
уровней
символьных
ссылок (POSIX.1-2001).
EMEDIUMTYPE
Неправильный
тип
носителя.
EMFILE
Too many open files (POSIX.1-2001). Commonly caused by exceeding the
RLIMIT_NOFILE resource limit described in getrlimit(2). Can
also be caused by exceeding the limit specified in
/proc/sys/fs/nr_open.
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
The named attribute does not exist, or the process has no access to this
attribute; see xattr(7).
In POSIX.1-2001 (XSI STREAMS option), this error was described as «No
message is available on the STREAM head read queue».
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
Invalid cross-device link (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 == ...) { ... } }

Note that the POSIX threads APIs do not set errno on
error. Instead, on failure they return an error number as the function
result. These error numbers have the same meanings as the error numbers
returned in errno by other APIs.

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

СМ. ТАКЖЕ

errno(1), err(3), error(3), perror(3),
strerror(3)

ПЕРЕВОД

Русский
перевод
этой
страницы
руководства
был сделан
Azamat Hackimov <azamat.hackimov@gmail.com>, Yuri Kozlov
<yuray@komyakino.ru> и Иван
Павлов
<pavia00@gmail.com>

Этот
перевод
является
бесплатной
документацией;
прочитайте
Стандартную
общественную
лицензию GNU
версии 3
или более
позднюю,
чтобы
узнать об
условиях
авторского
права. Мы не
несем
НИКАКОЙ
ОТВЕТСТВЕННОСТИ.

Если вы
обнаружите
ошибки в
переводе
этой
страницы
руководства,
пожалуйста,
отправьте
электронное
письмо на
man-pages-ru-talks@lists.sourceforge.net.

Errno 0:
Errno 1: Operation not permitted
Errno 2: No such file or directory
Errno 3: No such process
Errno 4: Interrupted system call
Errno 5: Input/output error
Errno 6: No such device or address
Errno 7: Argument list too long
Errno 8: Exec format error
Errno 9: Bad file descriptor
Errno 10: No child processes
Errno 11: Resource temporarily unavailable
Errno 12: Cannot allocate memory
Errno 13: Permission denied
Errno 14: Bad address
Errno 15: Block device required
Errno 16: Device or resource busy
Errno 17: File exists
Errno 18: Invalid cross-device link
Errno 19: No such device
Errno 20: Not a directory
Errno 21: Is a directory
Errno 22: Invalid argument
Errno 23: Too many open files in system
Errno 24: Too many open files
Errno 25: Inappropriate ioctl for device
Errno 26: Text file busy
Errno 27: File too large
Errno 28: No space left on device
Errno 29: Illegal seek
Errno 30: Read-only file system
Errno 31: Too many links
Errno 32: Broken pipe
Errno 33: Numerical argument out of domain
Errno 34: Numerical result out of range
Errno 35: Resource deadlock avoided
Errno 36: File name too long
Errno 37: No locks available
Errno 38: Function not implemented
Errno 39: Directory not empty
Errno 40: Too many levels of symbolic links
Errno 41: Unknown error 41
Errno 42: No message of desired type
Errno 43: Identifier removed
Errno 44: Channel number out of range
Errno 45: Level 2 not synchronized
Errno 46: Level 3 halted
Errno 47: Level 3 reset
Errno 48: Link number out of range
Errno 49: Protocol driver not attached
Errno 50: No CSI structure available
Errno 51: Level 2 halted
Errno 52: Invalid exchange
Errno 53: Invalid request descriptor
Errno 54: Exchange full
Errno 55: No anode
Errno 56: Invalid request code
Errno 57: Invalid slot
Errno 58: Unknown error 58
Errno 59: Bad font file format
Errno 60: Device not a stream
Errno 61: No data available
Errno 62: Timer expired
Errno 63: Out of streams resources
Errno 64: Machine is not on the network
Errno 65: Package not installed

If you find this page
helpful, please consider
visiting my sponsors.
Your ad revenue
supports this site.

Errno 66: Object is remote
Errno 67: Link has been severed
Errno 68: Advertise error
Errno 69: Srmount error
Errno 70: Communication error on send
Errno 71: Protocol error
Errno 72: Multihop attempted
Errno 73: RFS specific error
Errno 74: Bad message
Errno 75: Value too large for defined data type
Errno 76: Name not unique on network
Errno 77: File descriptor in bad state
Errno 78: Remote address changed
Errno 79: Can not access a needed shared library
Errno 80: Accessing a corrupted shared library
Errno 81: .lib section in a.out corrupted
Errno 82: Attempting to link in too many shared libraries
Errno 83: Cannot exec a shared library directly
Errno 84: Invalid or incomplete multibyte or wide character
Errno 85: Interrupted system call should be restarted
Errno 86: Streams pipe error
Errno 87: Too many users
Errno 88: Socket operation on non-socket
Errno 89: Destination address required
Errno 90: Message too long
Errno 91: Protocol wrong type for socket
Errno 92: Protocol not available
Errno 93: Protocol not supported
Errno 94: Socket type not supported
Errno 95: Operation not supported
Errno 96: Protocol family not supported
Errno 97: Address family not supported by protocol
Errno 98: Address already in use
Errno 99: Cannot assign requested address
Errno 100: Network is down
Errno 101: Network is unreachable
Errno 102: Network dropped connection on reset
Errno 103: Software caused connection abort
Errno 104: Connection reset by peer
Errno 105: No buffer space available
Errno 106: Transport endpoint is already connected
Errno 107: Transport endpoint is not connected
Errno 108: Cannot send after transport endpoint shutdown
Errno 109: Too many references: cannot splice
Errno 110: Connection timed out
Errno 111: Connection refused
Errno 112: Host is down
Errno 113: No route to host
Errno 114: Operation already in progress
Errno 115: Operation now in progress
Errno 116: Stale NFS file handle
Errno 117: Structure needs cleaning
Errno 118: Not a XENIX named type file
Errno 119: No XENIX semaphores available
Errno 120: Is a named type file
Errno 121: Remote I/O error
Errno 122: Disk quota exceeded
Errno 123: No medium found
Errno 124: Wrong medium type
Errno 125: Operation canceled
Errno 126: Required key not available
Errno 127: Key has expired
Errno 128: Key has been revoked
Errno 129: Key was rejected by service
Errno 130: Owner died
Errno 131: State not recoverable
Errno 132: Unknown error 132

Время на прочтение
13 мин

Количество просмотров 77K

Введение

Ошибки, увы, неизбежны, поэтому их обработка занимает очень важное место в программировании. И если алгоритмические ошибки можно выявить и исправить во время написания и тестирования программы, то ошибок времени выполнения избежать нельзя в принципе. Сегодня мы рассмотрим функции стандартной библиотеки (C Standard Library) и POSIX, используемые в обработке ошибок.

Переменная errno и коды ошибок

<errno.h>

errno – переменная, хранящая целочисленный код последней ошибки. В каждом потоке существует своя локальная версия errno, чем и обусловливается её безопасность в многопоточной среде. Обычно errno реализуется в виде макроса, разворачивающегося в вызов функции, возвращающей указатель на целочисленный буфер. При запуске программы значение errno равно нулю.

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

Стандарт ISO C определяет следующие коды:

  • EDOM – (Error domain) ошибка области определения.
  • EILSEQ – (Error invalid sequence) ошибочная последовательность байтов.
  • ERANGE – (Error range) результат слишком велик.

Прочие коды ошибок (несколько десятков) и их описания определены в стандарте POSIX. Кроме того, в спецификациях стандартных функций обычно указываются используемые ими коды ошибок и их описания.

Нехитрый скрипт печатает в консоль коды ошибок, их символические имена и описания:

#!/usr/bin/perl

use strict;
use warnings;

use Errno;

foreach my $err (sort keys (%!)) {
    $! = eval "Errno::$err";
    printf "%20s %4d   %s\n", $err, $! + 0, $!
}

Если вызов функции завершился ошибкой, то она устанавливает переменную errno в ненулевое значение. Если же вызов прошёл успешно, функция обычно не проверяет и не меняет переменную errno. Поэтому перед вызовом функции её нужно установить в 0.

Пример:

/* convert from UTF16 to UTF8 */
errno = 0;	
n_ret = iconv(icd, (char **) &p_src, &n_src, &p_dst, &n_dst);   
	
if (n_ret == (size_t) -1) {
    VJ_PERROR();
    if (errno == E2BIG)  
        fprintf(stderr, " Error : input conversion stopped due to lack of space in the output buffer\n");
    else if (errno == EILSEQ)  
        fprintf(stderr, " Error : input conversion stopped due to an input byte that does not belong to the input codeset\n");
    else if (errno == EINVAL)  
        fprintf(stderr, " Error : input conversion stopped due to an incomplete character or shift sequence at the end of the input buffer\n");
/* clean the memory */   
    free(p_out_buf);
    errno = 0;
    n_ret = iconv_close(icd);      
    if (n_ret == (size_t) -1)  
        VJ_PERROR();
    return (size_t) -1; 
}

Как видите, описания ошибок в спецификации функции iconv() более информативны, чем в <errno.h>.

Функции работы с errno

Получив код ошибки, хочется сразу получить по нему её описание. К счастью, ISO C предлагает целый набор полезных функций.

<stdio.h>

void perror(const char *s);

Печатает в stderr содержимое строки s, за которой следует двоеточие, пробел и сообщение об ошибке. После чего печатает символ новой строки '\n'.

Пример:

/*
//  main.c
//  perror example
//
//  Created by Ariel Feinerman on 23/03/17.
//  Copyright  2017 Feinerman Research, Inc. All rights reserved.
*/

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>

int main(int argc, const char * argv[]) 
{
    // Generate unique filename.
    char *file_name = tmpnam((char[L_tmpnam]){0});
   
    errno = 0;
    FILE *file = fopen(file_name, "rb");

    if (file) {
        // Do something useful. 
        fclose(file);
    }
    else {
        perror("fopen() ");
    }
	
    return EXIT_SUCCESS;
}

<string.h>

char* strerror(int errnum);
Возвращает строку, содержащую описание ошибки errnum. Язык сообщения зависит от локали (немецкий, иврит и даже японский), но обычно поддерживается лишь английский.

/*
//  main.c
//  strerror example
//
//  Created by Ariel Feinerman on 23/03/17.
//  Copyright  2017 Feinerman Research, Inc. All rights reserved.
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <errno.h>

int main(int argc, const char * argv[]) 
{
    // Generate unique filename.
    char *file_name = tmpnam((char[L_tmpnam]){0});

    errno = 0;
    FILE *file = fopen(file_name, "rb");
    // Save error number. 
    errno_t error_num = errno;
	
    if (file) {
        // Do something useful. 
        fclose(file);
    }
    else {
        char *errorbuf = strerror(error_num);
        fprintf(stderr, "Error message : %s\n", errorbuf);
    }
    
    return EXIT_SUCCESS;
}

strerror() не безопасная функция. Во-первых, возвращаемая ею строка не является константной. При этом она может храниться в статической или в динамической памяти в зависимости от реализации. В первом случае её изменение приведёт к ошибке времени выполнения. Во-вторых, если вы решите сохранить указатель на строку, и после вызовите функцию с новым кодом, все прежние указатели будут указывать уже на новую строку, ибо она использует один буфер для всех строк. В-третьих, её поведение в многопоточной среде не определено в стандарте. Впрочем, в QNX она объявлена как thread safe.

Поэтому в новом стандарте ISO C11 были предложены две очень полезные функции.

size_t strerrorlen_s(errno_t errnum);

Возвращает длину строки с описанием ошибки errnum.

errno_t strerror_s(char *buf, rsize_t buflen, errno_t errnum);

Копирует строку с описание ошибки errnum в буфер buf длиной buflen.

Пример:

/*
//  main.c
//  strerror_s example 
//
//  Created by Ariel Feinerman on 23/02/17.
//  Copyright  2017 Feinerman Research, Inc. All rights reserved.
*/

#define __STDC_WANT_LIB_EXT1__ 1
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <errno.h>

int main(int argc, const char * argv[]) 
{
    // Generate unique filename.
    char *file_name = tmpnam((char[L_tmpnam]){0});
	
    errno = 0;
    FILE *file = fopen(file_name, "rb");
    // Save error number. 
    errno_t error_num = errno;

    if (file) {
        // Do something useful. 
        fclose(file);
    }
    else {
#ifdef __STDC_LIB_EXT1__
    size_t error_len = strerrorlen_s(errno) + 1;
    char error_buf[error_len];
    strerror_s(error_buf, error_len, errno);
    fprintf(stderr, "Error message : %s\n", error_buf);
#endif
    }
	
    return EXIT_SUCCESS;
}

Функции входят в Annex K (Bounds-checking interfaces), вызвавший много споров. Он не обязателен к выполнению и целиком не реализован ни в одной из свободных библиотек. Open Watcom C/C++ (Windows), Slibc (GNU libc) и Safe C Library (POSIX), в последней, к сожалению, именно эти две функции не реализованы. Тем не менее, их можно найти в коммерческих средах разработки и системах реального времени, Embarcadero RAD Studio, INtime RTOS, QNX.

Стандарт POSIX.1-2008 определяет следующие функции:

char *strerror_l(int errnum, locale_t locale);

Возвращает строку, содержащую локализованное описание ошибки errnum, используя locale. Безопасна в многопоточной среде. Не реализована в Mac OS X, FreeBSD, NetBSD, OpenBSD, Solaris и прочих коммерческих UNIX. Реализована в Linux, MINIX 3 и Illumos (OpenSolaris).

Пример:

/*
 //  main.c
 //  strerror_l example – works on Linux, MINIX 3, Illumos
 //
 //  Created by Ariel Feinerman on 23/03/17.
 //  Copyright  2017 Feinerman Research, Inc. All rights reserved.
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <errno.h>

#include <locale.h>

int main(int argc, const char * argv[]) 
{
    locale_t locale = newlocale(LC_ALL_MASK, "fr_FR.UTF-8", (locale_t) 0);
    
    if (!locale) {
        fprintf(stderr, "Error: cannot create locale.");
        exit(EXIT_FAILURE);
    }

    // Generate unique filename.
    char *file_name = tmpnam((char[L_tmpnam]){0});
	
    errno = 0;
    FILE *file = fopen(tmpnam(file_name, "rb");
    // Save error number. 
    errno_t error_num = errno;

    if (file) {
        // Do something useful. 
        fclose(file);
    }
    else {
        char *error_buf = strerror_l(errno, locale);
        fprintf(stderr, "Error message : %s\n", error_buf);
    }
	
    freelocale(locale);
	
    return EXIT_SUCCESS;
}

Вывод:

Error message : Aucun fichier ou dossier de ce type

int strerror_r(int errnum, char *buf, size_t buflen);

Копирует строку с описание ошибки errnum в буфер buf длиной buflen. Если buflen меньше длины строки, лишнее обрезается. Безопасна в многоготочной среде. Реализована во всех UNIX.

Пример:

/*
//  main.c
//  strerror_r POSIX example
//
//  Created by Ariel Feinerman on 25/02/17.
//  Copyright  2017 Feinerman Research, Inc. All rights reserved.
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <errno.h>

#define MSG_LEN 1024 

int main(int argc, const char * argv[]) 
{
    // Generate unique filename.
    char *file_name = tmpnam((char[L_tmpnam]){0});
    
    errno = 0;
    FILE *file = fopen(file_name, "rb");
    // Save error number. 
    errno_t error_num = errno;	
	
    if (file) {
        // Do something useful.
        fclose(file);
    }
    else {
        char error_buf[MSG_LEN];
        errno_t error = strerror_r (error_num, error_buf, MSG_LEN);
		
        switch (error) {
            case EINVAL:
                    fprintf (stderr, "strerror_r() failed: invalid error code, %d\n", error);
                    break;
            case ERANGE:
                    fprintf (stderr, "strerror_r() failed: buffer too small: %d\n", MSG_LEN);
            case 0:
                    fprintf(stderr, "Error message : %s\n", error_buf);
                    break;
            default: 
                    fprintf (stderr, "strerror_r() failed: unknown error, %d\n", error);
                    break;
        }
    }
    
    return EXIT_SUCCESS;
}

Увы, никакого аналога strerrorlen_s() в POSIX не определили, поэтому длину строки можно выяснить лишь экспериментальным путём. Обычно 300 символов хватает за глаза. GNU C Library в реализации strerror() использует буфер длиной в 1024 символа. Но мало ли, а вдруг?

Пример:

/*
 //  main.c
 //  strerror_r safe POSIX example
 //
 //  Created by Ariel Feinerman on 23/03/17.
 //  Copyright  2017 Feinerman Research, Inc. All rights reserved.
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <errno.h>

#define MSG_LEN 1024 
#define MUL_FACTOR 2

int main(int argc, const char * argv[]) 
{
    // Generate unique filename.
    char *file_name = tmpnam((char[L_tmpnam]){0});
	
    errno = 0;
    FILE *file = fopen(file_name, "rb");
    // Save error number. 
    errno_t error_num = errno;
	
    if (file) {
        // Do something useful.
        fclose(file);
    }
    else {
        errno_t error = 0;
        size_t error_len = MSG_LEN; 
		
        do {
            char error_buf[error_len];
            error = strerror_r (error_num, error_buf, error_len);
            switch (error) {
                    case 0:
                            fprintf(stderr, "File : %s\nLine : %d\nCurrent function : %s()\nFailed function : %s()\nError message : %s\n", __FILE__, __LINE__, __func__, "fopen", error_buf);
	                    break;
                    case ERANGE: 
                            error_len *= MUL_FACTOR;
                            break;
                    case EINVAL: 
                            fprintf (stderr, "strerror_r() failed: invalid error code, %d\n", error_num);
                            break;
                    default:
                            fprintf (stderr, "strerror_r() failed: unknown error, %d\n", error);
                            break;
            }
			
        } while (error == ERANGE);
    }
    
    return EXIT_SUCCESS;
}

Вывод:

File : /Users/ariel/main.c
Line : 47
Current function : main()
Failed function : fopen()
Error message : No such file or directory

Макрос assert()

<assert.h>

void assert(expression)

Макрос, проверяющий условие expression (его результат должен быть числом) во время выполнения. Если условие не выполняется (expression равно нулю), он печатает в stderr значения __FILE__, __LINE__, __func__ и expression в виде строки, после чего вызывает функцию abort().

/*
//  main.c
//  assert example
//
//  Created by Ariel Feinerman on 23/03/17.
//  Copyright  2017 Feinerman Research, Inc. All rights reserved.
*/

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>

#include <math.h>

int main(int argc, const char * argv[]) {
    double x = -1.0;
    assert(x >= 0.0);
    printf("sqrt(x) = %f\n", sqrt(x));   
    
    return EXIT_SUCCESS;
}

Вывод:

Assertion failed: (x >= 0.0), function main, file /Users/ariel/main.c, line 17.

Если макрос NDEBUG определён перед включением <assert.h>, то assert() разворачивается в ((void) 0) и не делает ничего. Используется в отладочных целях.

Пример:

/*
//  main.c
//  assert_example
//
//  Created by Ariel Feinerman on 23/03/17.
//  Copyright  2017 Feinerman Research, Inc. All rights reserved.
*/

#NDEBUG

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>

#include <math.h>

int main(int argc, const char * argv[]) {
    double x = -1.0;
    assert(x >= 0.0);
    printf("sqrt(x) = %f\n", sqrt(x));   
    
    return EXIT_SUCCESS;
}

Вывод:

sqrt(x) = nan

Функции atexit(), exit() и abort()

<stdlib.h>

int atexit(void (*func)(void));

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

_Noreturn void exit(int exit_code);

Вызывает нормальное завершение программы, возвращает в среду число exit_code. ISO C стандарт определяет всего три возможных значения: 0, EXIT_SUCCESS и EXIT_FAILURE. При этом вызываются функции, зарегистрированные через atexit(), сбрасываются и закрываются потоки ввода — вывода, уничтожаются временные файлы, после чего управление передаётся в среду. Функция exit() вызывается в main() при выполнении return или достижении конца программы.

Главное преимущество exit() в том, что она позволяет завершить программу не только из main(), но и из любой вложенной функции. К примеру, если в глубоко вложенной функции выполнилось (или не выполнилось) некоторое условие, после чего дальнейшее выполнение программы теряет всякий смысл. Подобный приём (early exit) широко используется при написании демонов, системных утилит и парсеров. В интерактивных программах с бесконечным главным циклом exit() можно использовать для выхода из программы при выборе нужного пункта меню.

Пример:

/*
//  main.c
//  exit example
//
//  Created by Ariel Feinerman on 17/03/17.
//  Copyright  2017 Feinerman Research, Inc. All rights reserved.
*/

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

void third_2(void) 
{
    printf("third #2\n");          // Does not print.
}

void third_1(void) 
{
    printf("third #1\n");          // Does not print.
}

void second(double num) 
{
    printf("second : before exit()\n");	// Prints.
    
    if ((num < 1.0f) && (num > -1.0f)) {
        printf("asin(%.1f) = %.3f\n", num, asin(num));
        exit(EXIT_SUCCESS);
    }
    else {
        fprintf(stderr, "Error: %.1f is beyond the range [-1.0; 1.0]\n", num);
        exit(EXIT_FAILURE);
    }
    
    printf("second : after exit()\n");	// Does not print.
}

void first(double num) 
{
    printf("first : before second()\n")
    second(num);
    printf("first : after second()\n");          // Does not print.
}

int main(int argc, const char * argv[]) 
{
    atexit(third_1); // Register first handler. 
    atexit(third_2); // Register second handler.
    
    first(-3.0f);
    
    return EXIT_SUCCESS;
}

Вывод:

first : before second()
second : before exit()
Error: -3.0 is beyond the range [-1.0; 1.0]
third #2
third #1

_Noreturn void abort(void);

Вызывает аварийное завершение программы, если сигнал не был перехвачен обработчиком сигналов. Временные файлы не уничтожаются, закрытие потоков определяется реализацией. Самое главное отличие вызовов abort() и exit(EXIT_FAILURE) в том, что первый посылает программе сигнал SIGABRT, его можно перехватить и произвести нужные действия перед завершением программы. Записывается дамп памяти программы (core dump file), если они разрешены. При запуске в отладчике он перехватывает сигнал SIGABRT и останавливает выполнение программы, что очень удобно в отладке.

Пример:

/*
//  main.c
//  abort example
//
//  Created by Ariel Feinerman on 17/02/17.
//  Copyright  2017 Feinerman Research, Inc. All rights reserved.
*/

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

void third_2(void) 
{
    printf("third #2\n");          // Does not print.
}

void third_1(void) 
{
    printf("third #1\n");          // Does not print.
}

void second(double num) 
{
    printf("second : before exit()\n");	// Prints.
    
    if ((num < 1.0f) && (num > -1.0f)) {
        printf("asin(%.1f) = %.3f\n", num, asin(num));
        exit(EXIT_SUCCESS);
    }
    else {
        fprintf(stderr, "Error: %.1f is beyond the range [-1.0; 1.0]\n", num);
        abort();
    }
    
    printf("second : after exit()\n");	// Does not print.
}

void first(double num) 
{
    printf("first : before second()\n");
    second(num);
    printf("first : after second()\n");          // Does not print.
}

int main(int argc, const char * argv[]) 
{
    atexit(third_1); // register first handler 
    atexit(third_2); // register second handler
    
    first(-3.0f);
    
    return EXIT_SUCCESS;
}

Вывод:

first : before second()
second : before exit()
Error: -3.0 is beyond the range [-1.0; 1.0]
Abort trap: 6

Вывод в отладчике:

$ lldb abort_example 
(lldb) target create "abort_example"
Current executable set to 'abort_example' (x86_64).
(lldb) run
Process 22570 launched: '/Users/ariel/abort_example' (x86_64)
first : before second()
second : before exit()
Error: -3.0 is beyond the range [-1.0; 1.0]
Process 22570 stopped
* thread #1: tid = 0x113a8, 0x00007fff89c01286 libsystem_kernel.dylib`__pthread_kill + 10, queue = 'com.apple.main-thread', stop reason = signal SIGABRT
    frame #0: 0x00007fff89c01286 libsystem_kernel.dylib`__pthread_kill + 10
libsystem_kernel.dylib`__pthread_kill:
->  0x7fff89c01286 <+10>: jae    0x7fff89c01290            ; <+20>
    0x7fff89c01288 <+12>: movq   %rax, %rdi
    0x7fff89c0128b <+15>: jmp    0x7fff89bfcc53            ; cerror_nocancel
    0x7fff89c01290 <+20>: retq   
(lldb) 

В случае критической ошибки нужно использовать функцию abort(). К примеру, если при выделении памяти или записи файла произошла ошибка. Любые дальнейшие действия могут усугубить ситуацию. Если завершить выполнение обычным способом, при котором производится сброс потоков ввода — вывода, можно потерять ещё неповрежденные данные и временные файлы, поэтому самым лучшим решением будет записать дамп и мгновенно завершить программу.

В случае же некритической ошибки, например, вы не смогли открыть файл, можно безопасно выйти через exit().

Функции setjmp() и longjmp()

Вот мы и подошли к самому интересному – функциям нелокальных переходов. setjmp() и longjmp() работают по принципу goto, но в отличие от него позволяют перепрыгивать из одного места в другое в пределах всей программы, а не одной функции.

<setjmp.h>

int setjmp(jmp_buf env);

Сохраняет информацию о контексте выполнения программы (регистры микропроцессора и прочее) в env. Возвращает 0, если была вызвана напрямую или value, если из longjmp().

void longjmp(jmp_buf env, int value);

Восстанавливает контекст выполнения программы из env, возвращает управление setjmp() и передаёт ей value.

Пример:

/*
//  main.c
//  setjmp simple
//
//  Created by Ariel Feinerman on 18/02/17.
//  Copyright  2017 Feinerman Research, Inc. All rights reserved.
*/

#include <stdio.h>
#include <stdlib.h>
#include <setjmp.h>

static jmp_buf buf;

void second(void) 
{
    printf("second : before longjmp()\n");	// prints
    longjmp(buf, 1);						// jumps back to where setjmp was called – making setjmp now return 1
    printf("second : after longjmp()\n");	// does not prints
	
    // <- Here is the point that is never reached. All impossible cases like your own house in Miami, your million dollars, your nice girl, etc.
}

void first(void) 
{
    printf("first : before second()\n");
    second();
    printf("first : after second()\n");          // does not print
}

int main(int argc, const char * argv[]) 
{
    if (!setjmp(buf))
        first();                // when executed, setjmp returned 0
    else                        // when longjmp jumps back, setjmp returns 1
        printf("main\n");       // prints
    
    return EXIT_SUCCESS;
}

Вывод:

first : before second()
second : before longjmp()
main

Используя setjmp() и longjmp() можно реализовать механизм исключений. Во многих языках высокого уровня (например, в Perl) исключения реализованы через них.

Пример:

/*
//  main.c
//  exception simple
//
//  Created by Ariel Feinerman on 18/02/17.
//  Copyright  2017 Feinerman Research, Inc. All rights reserved.
*/

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

#include <setjmp.h>

#define str(s) #s

static jmp_buf buf;

typedef enum {
    NO_EXCEPTION    = 0,
    RANGE_EXCEPTION = 1,
    NUM_EXCEPTIONS
} exception_t;

static char *exception_name[NUM_EXCEPTIONS] = {
	
    str(NO_EXCEPTION),
    str(RANGE_EXCEPTION)
};

float asin_e(float num) 
{
    if ((num < 1.0f) && (num > -1.0f)) {
        return asinf(num);
    }	
    else {
        longjmp(buf, RANGE_EXCEPTION);        // | @throw  
    }
}

void do_work(float num) 
{
    float res = asin_e(num);
    printf("asin(%f) = %f\n", num, res);         
}

int main(int argc, const char * argv[]) 
{
    exception_t exc = NO_EXCEPTION;
    if (!(exc = setjmp(buf))) {        // |	
        do_work(-3.0f);                // | @try
    }                                  // |
    else {                                                                               // | 
        fprintf(stderr, "%s was hadled in %s()\n", exception_name[exc], __func__);       // | @catch
    }                                                                                    // | 
	
    return EXIT_SUCCESS;
}

Вывод:

RANGE_EXCEPTION was hadled in main()

Внимание! Функции setjmp() и longjmp() в первую очередь применяются в системном программировании, и их использование в клиентском коде не рекомендуется. Их применение ухудшает читаемость программы и может привести к непредсказуемым ошибкам. Например, что произойдёт, если вы прыгните не вверх по стеку – в вызывающую функцию, а в параллельную, уже завершившую выполнение?

Информация

  • стандарт ISO/IEC C (89/99/11)
  • Single UNIX Specifcation, Version 4, 2016 Edition
  • The Open Group Base Specifcations Issue 7, 2016 Edition (POSIX.1-2008)
  • SEI CERT C Coding Standard
  • cправочная информация среды программирования
  • справочная информация операционной системы (man pages)
  • заголовочные файлы (/usr/include)
  • исходные тексты библиотеки (C Standard Library)

Programmers should handle all kinds of errors to protect the program from failure.

In C programming language, there is no direct support for error handling. You have to detect the failure and handle the error. In C programming language, return values represents success or failure. Inside a C program, when a function fails, you should handle the errors accordingly, or at least record the errors in a log file.

When you are running some program on Linux environment, you might notice that it gives some error number. For example, “Error no is : 17”, which doesn’t really say much. You really need to know what error number 17 means.

This article shows all available error numbers along with it descriptions. This article might be a handy reference for you, when you encounter an error number and you would like to know what it means.

  • In C programming language, there is an external variable called “errno”.
  • From this errno variable you can use some error handling functions to find out the error description and handle it appropriately.
  • You have to include errno.h header file to use external variable errno.
  • perror function prints error description in standard error.
  • The strerror function returns a string describing the error code passed in the argument errnum.

The following C code snippet tries to open a file through open system call. There are two flags in the open call. O_CREAT flag is to create a file, if the file does not exist. O_EXCL flag is used with O_CREAT, if the file is already exist open call will fail with the proper error number.

$ cat fileopen.c
#include <stdio.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
main()
{
// Declaration of a file descriptor
int fd;

// Opening a file
fd = open("/root/sasikala/testing",O_CREAT|O_EXCL);
// If Open is failed
if ( fd < 0 ) {
        printf("Opening file : Failed\n");
        printf ("Error no is : %d\n", errno);
        printf("Error description is : %s\n",strerror(errno));
}
// If Open is success
else
        printf("Opening file : Success\n");

}

$ cc -o fileopen fileopen.c
$ ./fileopen

Opening file : Success

$ ./fileopen
Opening file : Failed
Error no is : 17
Error description is : File exists

At first execution, open got executed successfully, and it created the file since the file was not available. In next execution, it throws an error number 17, which is “File already exist”.

The following table shows list of error numbers and its descriptions in Linux operation system

ERROR CODE TABLE
Error number Error Code Error Description
1 EPERM Operation not permitted
2 ENOENT No such file or directory
3 ESRCH No such process
4 EINTR Interrupted system call
5 EIO I/O error
6 ENXIO No such device or address
7 E2BIG Argument list too long
8 ENOEXEC Exec format error
9 EBADF Bad file number
10 ECHILD No child processes
11 EAGAIN Try again
12 ENOMEM Out of memory
13 EACCES Permission denied
14 EFAULT Bad address
15 ENOTBLK Block device required
16 EBUSY Device or resource busy
17 EEXIST File exists
18 EXDEV Cross-device link
19 ENODEV No such device
20 ENOTDIR Not a directory
21 EISDIR Is a directory
22 EINVAL Invalid argument
23 ENFILE File table overflow
24 EMFILE Too many open files
25 ENOTTY Not a typewriter
26 ETXTBSY Text file busy
27 EFBIG File too large
28 ENOSPC No space left on device
29 ESPIPE Illegal seek
30 EROFS Read-only file system
31 EMLINK Too many links
32 EPIPE Broken pipe
33 EDOM Math argument out of domain of func
34 ERANGE Math result not representable
35 EDEADLK Resource deadlock would occur
36 ENAMETOOLONG File name too long
37 ENOLCK No record locks available
38 ENOSYS Function not implemented
39 ENOTEMPTY Directory not empty
40 ELOOP Too many symbolic links encountered
42 ENOMSG No message of desired type
43 EIDRM Identifier removed
44 ECHRNG Channel number out of range
45 EL2NSYNC Level 2 not synchronized
46 EL3HLT Level 3 halted
47 EL3RST Level 3 reset
48 ELNRNG Link number out of range
49 EUNATCH Protocol driver not attached
50 ENOCSI No CSI structure available
51 EL2HLT Level 2 halted
52 EBADE Invalid exchange
53 EBADR Invalid request descriptor
54 EXFULL Exchange full
55 ENOANO No anode
56 EBADRQC Invalid request code
57 EBADSLT Invalid slot
59 EBFONT Bad font file format
60 ENOSTR Device not a stream
61 ENODATA No data available
62 ETIME Timer expired
63 ENOSR Out of streams resources
64 ENONET Machine is not on the network
65 ENOPKG Package not installed
66 EREMOTE Object is remote
67 ENOLINK Link has been severed
68 EADV Advertise error
69 ESRMNT Srmount error
70 ECOMM Communication error on send
71 EPROTO Protocol error
72 EMULTIHOP Multihop attempted
73 EDOTDOT RFS specific error
74 EBADMSG Not a data message
75 EOVERFLOW Value too large for defined data type
76 ENOTUNIQ Name not unique on network
77 EBADFD File descriptor in bad state
78 EREMCHG Remote address changed
79 ELIBACC Can not access a needed shared library
80 ELIBBAD Accessing a corrupted shared library
81 ELIBSCN .lib section in a.out corrupted
82 ELIBMAX Attempting to link in too many shared libraries
83 ELIBEXEC Cannot exec a shared library directly
84 EILSEQ Illegal byte sequence
85 ERESTART Interrupted system call should be restarted
86 ESTRPIPE Streams pipe error
87 EUSERS Too many users
88 ENOTSOCK Socket operation on non-socket
89 EDESTADDRREQ Destination address required
90 EMSGSIZE Message too long
91 EPROTOTYPE Protocol wrong type for socket
92 ENOPROTOOPT Protocol not available
93 EPROTONOSUPPORT Protocol not supported
94 ESOCKTNOSUPPORT Socket type not supported
95 EOPNOTSUPP Operation not supported on transport endpoint
96 EPFNOSUPPORT Protocol family not supported
97 EAFNOSUPPORT Address family not supported by protocol
98 EADDRINUSE Address already in use
99 EADDRNOTAVAIL Cannot assign requested address
100 ENETDOWN Network is down
101 ENETUNREACH Network is unreachable
102 ENETRESET Network dropped connection because of reset
103 ECONNABORTED Software caused connection abort
104 ECONNRESET Connection reset by peer
105 ENOBUFS No buffer space available
106 EISCONN Transport endpoint is already connected
107 ENOTCONN Transport endpoint is not connected
108 ESHUTDOWN Cannot send after transport endpoint shutdown
109 ETOOMANYREFS Too many references: cannot splice
110 ETIMEDOUT Connection timed out
111 ECONNREFUSED Connection refused
112 EHOSTDOWN Host is down
113 EHOSTUNREACH No route to host
114 EALREADY Operation already in progress
115 EINPROGRESS Operation now in progress
116 ESTALE Stale NFS file handle
117 EUCLEAN Structure needs cleaning
118 ENOTNAM Not a XENIX named type file
119 ENAVAIL No XENIX semaphores available
120 EISNAM Is a named type file
121 EREMOTEIO Remote I/O error
122 EDQUOT Quota exceeded
123 ENOMEDIUM No medium found
124 EMEDIUMTYPE Wrong medium type
125 ECANCELED Operation Canceled
126 ENOKEY Required key not available
127 EKEYEXPIRED Key has expired
128 EKEYREVOKED Key has been revoked
129 EKEYREJECTED Key was rejected by service
130 EOWNERDEAD Owner died
131 ENOTRECOVERABLE State not recoverable

When you see an error number thrown by a C program on a Linux environment, you might find the above table handy to identify what those error number means. Make sure to bookmark this article for future reference.

Понравилась статья? Поделить с друзьями:
  • Errno 13 permission denied python ошибка
  • Errno 103 anydesk ошибка
  • Errcur2000 ошибка альфа банк что это
  • Err8 стиральная машина haier ошибка
  • Err62 ошибка уаз