Библиотечные функции, как правило, не устанавливают значение переменной errno, а код возврата различен для разных функций. Для уточнения возвращаемого значения библиотечной функции необходимо обратиться к электронному справочнику man(1) .
Поскольку базовым способом получения услуг ядра являются системные вызовы, рассмотрим более подробно обработку ошибок в этом случае.
Следует обратить внимание, что значение errno не обнуляется следующим нормально завершившимся системным вызовом. Таким образом, значение errno имеет смысл только после системного вызова, который завершился с ошибкой.
Стандарт ANSI С определяет две функции, помогающие сообщить причину ошибочной ситуации: strerror(3C) и perror(3C) .
Функция принимает в качестве аргумента errnum номер ошибки и возвращает указатель на строку, содержащую сообщение о причине ошибочной ситуации.
Функция выводит в стандартный поток сообщений об ошибках информацию об ошибочной ситуации, основываясь на значении переменной errno. Строка s, передаваемая функции, предваряет это сообщение и может служить дополнительной информацией, например содержа название функции или программы, в которой произошла ошибка.
Эти функции используются, в частности, командным интерпретатором и большинством стандартных утилит UNIX. Например:
В табл. 2.1 приведены наиболее общие ошибки системных вызовов, включая сообщения, которые обычно выводят функции strerror(3C) и perror(3C) , а также их краткое описание.
Таблица 2.1. Некоторые ошибки системных вызовов
Код ошибки и сообщение |
Описание |
E2BIG Arg list too long |
Размер списка аргументов, переданных системному вызову exec(2), плюс размер экспортируемых переменных окружения превышает ARG_MAX байт |
EACCESS Permission denied |
Попытка доступа к файлу с недостаточными правами для данного класса (определяемого эффективным UID и GID процесса и соответствующими идентификаторами файла) |
EAGAIN Resource temporarily unavailable |
Превышен предел использования некоторого ресурса, например, переполнена таблица процессов или пользователь превысил ограничение по количеству процессов с одинаковым UID. Причиной также может являться недостаток памяти или превышение соответствующего ограничения (см. раздел "Ограничения" далее в этой главе) |
EALREADY Operation already in progress |
Попытка операции с неблокируемым объектом, уже обслуживающим некоторую операцию |
EBADF Bad file number |
Попытка операции с файловым дескриптором, не адресующим никакой файл; также попытка операции чтения или записи с файловым дескриптором, полученным при открытии файла на запись или чтение, соответственно |
EBADFD File descriptor in bad state |
Файловый дескриптор не адресует открытый файл или попытка операции чтения с файловым дескриптором, полученным при открытии файла только на запись |
EBUSY Device busy |
Попытка монтирования устройства (файловой системы), которое уже примонтировано; попытка размонтировать файловую систему, имеющую открытые файлы; попытка обращения к недоступным ресурсам (семафоры, блокираторы и т.п.) |
ECHILD No child processes |
Вызов функции wait(2) процессом, не имеющим дочерних процессов или процессов, для которых уже был сделан вызов wait(2) |
EDQUOT Disk quota exceeded |
Попытка записи в файл, создание каталога или файла при превышении квоты пользователя на дисковые блоки, попытка создания файла при превышении пользовательской квоты на число inode |
EEXIST File exists |
Имя существующего файла использовано в недопустимом контексте, например, сделана попытка создания символической связи с именем уже существующего файла |
EFAULT Bad address |
Аппаратная ошибка при попытке использования системой аргумента функции, например, в качестве указателя передан недопустимый адрес |
EFBIG File too large |
Размер файла превысил установленное ограничение RLIMIT_FSIZE или максимально допустимый размер для данной файловой системы (см. раздел "Ограничения" далее в этой главе) |
EINPROGRESS Operation now in progress |
Попытка длительной операции (например, установление сетевого соединения) для неблокируемого объекта |
EINTR Interrupted system call |
Получение асинхронного сигнала, например, сигнала SIGINT или SIGQUIT, во время обработки системного вызова. Если выполнение процесса будет продолжено после обработки сигнала, прерванный системный вызов завершится с этой ошибкой |
EINVAL Invalid argument |
Передача неверного аргумента системному вызову. Например, размонтирование устройства (файловой системы), которое не было примонтировано. Другой пример — передача номера несуществующего сигнала системному вызову kill(2) |
EIO I/O error |
Ошибка ввода/вывода физического устройства |
EISDIR Is a directory |
Попытка операции, недопустимой для каталога, например, запись в каталог с помощью вызова write(2) |
ELOOP Number of symbolic links encountered during path name traversal exceeds MAXSYMLINKS |
При попытке трансляции имени файла было обнаружено недопустимо большое число символических связей, превышающее значение MAXSYMLINKS |
EMFILE Too many open files |
Число открытых файлов для процесса превысило максимальное значение OPEN_MAX |
ENAMETOOLONG File name too long |
Длина полного имени файла (включая путь) превысила максимальное значение PATH_MAX |
ENFILE File table overflow |
Переполнение файловой таблицы |
ENODEV No such device |
Попытка недопустимой операции для устройства. Например, попытка чтения устройства только для записи или операция для несуществующего устройства |
ENOENT No such file or directory |
Файл с указанным именем не существует или отсутствует каталог, указанный в полном имени файла |
ENOEXEC Exec format error |
Попытка запуска на выполнение файла, который имеет права на выполнение, но не является файлом допустимого исполняемого формата |
ENOMEM Not enough space |
При попытке запуска программы ( exec(2) ) или размещения памяти ( brk(2) ) размер запрашиваемой памяти превысил максимально возможный в системе |
ENOMSG No message of desired type |
Попытка получения сообщения определенного типа, которого не существует в очереди (см. раздел "Сообщения" в главе 3) |
ENOSPC No space left on device |
Попытка записи в файл или создания нового каталога при отсутствии свободного места на устройстве (в файловой системе) |
ENOSR Out of stream resources |
Отсутствие очередей или головных модулей при попытке открытия устройства STREAMS. Это состояние является временным. После освобождения соответствующих ресурсов другими процессами операция может пройти успешно |
ENOSTR Not a stream device |
Попытка применения операции, определенной для устройств типа STREAMS (например системного вызова putmsg(2) или getmsg(2) ), для устройства другого типа |
ENOTDIR Not a directory |
В операции, предусматривающей в качестве аргумента имя каталога, было указано имя файла другого типа (например, в пути для полного имени файла) |
ENOTTY Inappropriate ioctl for device |
Попытка системного вызова ioctl(2) для устройства, которое не является символьным |
EPERM Not owner |
Попытка модификации файла, способом, разрешенным только владельцу и суперпользователю и запрещенным остальным пользователям. Попытка операции, разрешенной только суперпользователю |
EPIPE Broken pipe |
Попытка записи в канал (pipe), для которого не существует процесса, принимающего данные. В этой ситуации процессу обычно отправляется соответствующий сигнал. Ошибка возвращается при игнорировании сигнала |
EROFS Read-only file system |
Попытка модификации файла или каталога для устройства (файловой системы), примонтированного только на чтение |
ESRCH No such process |
Процесс с указанным PID не существует в системе |