Операционная система UNIX - страница 44
с ошибкой, и все они могут быть определены с помощью переменной errno. Файл заголовков
Библиотечные функции, как правило, не устанавливают значение переменной errno, а код возврата различен для разных функций. Для уточнения возвращаемого значения библиотечной функции необходимо обратиться к электронному справочнику man(1).
Поскольку базовым способом получения услуг ядра являются системные вызовы, рассмотрим более подробно обработку ошибок в этом случае.
Переменная errno определена следующим образом:
>external int errno;
Следует обратить внимание, что значение errno не обнуляется следующим нормально завершившимся системным вызовом. Таким образом, значение errno имеет смысл только после системного вызова, который завершился с ошибкой.
Стандарт ANSI С определяет две функции, помогающие сообщить причину ошибочной ситуации: strerror(3C) и perror(3C).
Функция strerror(3C) имеет вид:
>#include
>char *strerror(int errnum);
Функция принимает в качестве аргумента errnum номер ошибки и возвращает указатель на строку, содержащую сообщение о причине ошибочной ситуации.
Функция perror(3C) объявлена следующим образом:
>#include
>#include
>void perror(const char *s);
Функция выводит в стандартный поток сообщений об ошибках информацию об ошибочной ситуации, основываясь на значении переменной errno. Строка s, передаваемая функции, предваряет это сообщение и может служить дополнительной информацией, например содержа название функции или программы, в которой произошла ошибка.
Следующий пример иллюстрирует использование этих двух функций:
>#include
>#include
>main(int argc, char *argv[]) {
> fprintf(stderr, "ENOMEM: %s\n", strerror(ENOMEM));
> errno = ENOEXEC;
> perror(argv[0]);
>}
Запустив программу, мы получим следующий результат на экране:
>$ a.out
>ENOMEM: Not enough space
>a.out: Exec format error
Эти функции используются, в частности, командным интерпретатором и большинством стандартных утилит UNIX. Например:
>$ rm does_not_exist
>does_not_exist: No such file or directory
ошибка ENOENT
>$ pg do_not_read
>do_not_read: Permission denied
ошибка EACCESS
>$
В табл. 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) процессом, не имеющим дочерних процессов или процессов, для которых уже был сделан вызов |