Обработка ошибок

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

Обычно в случае возникновения ошибки системные вызовы возвращают ?1 и устанавливают значение переменной errno, указывающее причину возникновения ошибки. Так, например, существует более десятка причин завершения вызова open(2) с ошибкой, и все они могут быть определены с помощью переменной errno. Файл заголовков <errno.h> содержит коды ошибок, зна­чения которых может принимать переменная errno, с краткими коммента­риями.

Библиотечные функции, как правило, не устанавливают значение перемен­ной errno, а код возврата различен для разных функций.

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

Переменная errno определена следующим образом: external int errno;

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

Стандарт ANSI С определяет две функции, помогающие сообщить причину

ОШИбоЧНОЙ ситуации: strerror(3C) и реггог(ЗС).

Функция strerror(3C) имеет вид:

#include <string.h>

char *strerror(int errnum);

Функция принимает в качестве аргумента errnum номер ошибки и возвращает указатель на строку, содержащую сообщение о причине ошибочной ситуации.

Функция реггог(зс) объявлена следующим образом:

#include <errno.h>

#include <stdio.h>

void perror(const char *s);

Функция выводит в стандартный поток сообщений об ошибках информацию об ошибочной ситуации, основываясь на значении переменной еrrno. Строка s, передаваемая функции, предваряет это сообщение и может служить дополнительной информацией, добавляя, например, название функции или программы, в которой произошла ошибка.

Использование этих двух функций:

#include <errno.h>

#include <stdio.h>

main(int argc, char *argv[])

{

fprintf(stderr, ?ENOMEM: %s\n", strerror(enomem));

ermo = ENOEXEC;

perror(argv[0]);

}


Результат выполнения:

ENOMEM: Not enough space

./program: exec format error


Таблицу с описанием ошибок системных вызовов можно найти в книге А.Робачевского по Unix.