Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лек_1_3_Системные вызовы.doc
Скачиваний:
0
Добавлен:
21.09.2019
Размер:
62.98 Кб
Скачать

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

Большинство системных вызовов возвращают в программу в качестве своего значения признак успеха: 0 − все сделано, (-1) − системный вызов завершился неудачей; реже возвращается некоторое содержательное значение при успехе (вроде дескриптора файла в open(), и (-1) при неудаче.

Проверка ошибок после работы системного вызова является необходимым условием написания хороших программ. Чтобы использовать средства обработки ошибок программа должна включить заголовочный файл "errno.h".

Знания о том, что произошла ошибка – мало. Нужно знать ее причину. Для этого у процесса есть специальная предопределенная переменная errno. Всякий раз, когда системный вызов завершается с ошибкой, errno устанавливается в одно из значений из набора предопределенных значений ошибок, которые определены в <errno.h>. Стандарт POSIX 2001 определяет большое число возможных ошибок, большинство из которых относится к сетям, межпроцессному. В man для каждого системного вызова описаны возможные значения errno, которые могут иметь место. Возможные значения определены через зарезервированные (операционной системой) символические имена. Имена начинаются с "E", содержат символы верхнего регистра или цифры.

Начальное значение errno при запуске программы равно 0. Переменную errno следует проверять лишь после того, как возникла ошибка и до того, как сделаны дальнейшие системные (или библиотечные) вызовы. Успешный системный вызов не восстанавливает errno в 0.

Обе функции strerror(3) и perror(3) производят одно и то же сообщение для любого данного кода ошибки; точный текст изменяется от системы к системе. В системе GNU сообщения довольно коротки; не имеются никаких многострочных сообщений или вложенных символов перевода строки. Каждое сообщение об ошибках начинается заголовочной буквой и не включает никакой пунктуации завершения.

#include <errno.h> /* коды ошибок */

extern int errno;

extern char *sys_errlist[];

int value;

if((value = sys_call(...)) < 0 )

{ printf("Error:%s(%d)\n", sys_errlist[errno], errno );

exit(errno); /* принудительное завершение программы */

}

Предопределенный массив sys_errlist, хранящийся в стандартной библиотеке, содержит строки-расшифровку смысла ошибок (по-английски). Посмотрите описание функции perror().

Функция perror(3) печатает сообщение об ошибках в поток stderr. Она выводит представленную в параметрах строку message, за которой следует двоеточие и пробел, а строка, описывающая значение errno:

include <stdio.h>

void perror (const char * message)

Более современная функция вывода сообщений об ошибке ‑ strerror(3), которая возвращает указатель на строку, соответствующую номеру ошибки, заданному параметром errnum:

include <string.h>

сhar * strerror ( int errnum) (функция)

Значение errnum обычно исходит из переменной errno.

Не следует изменять строку, возвращаемую strerror. Также, если в программе осуществляются последующие обращения к strerror(3), новая строка будет записана поверх старой. (Но гарантируется, что никакая библиотечная функция не вызовет strerror за вашей спиной).

Пример. Использование fprintf для вывода сообщения об ошибке:

if (some_system_call(param1, param2)<0)

{ fprintf(stderr,” %s: %d, %d: some_system_callfailed: %s\n”,

argv[0], param1, param2, strerror(errno));

return 1;

}

Пример значений переменной errno, которые она принимает при неудачном завершении системного вызова open (неполный список).

[EACCES]

доступ запрещен

[EAGAIN]

файл существует, но доступ к нему заблокирован

[EIO]

разрыв связи или ошибка при открытии псевдоустройства

[EISDIR]

указанный файл является каталогом и открывается на запись или чтение/запись.

[EMFILE]

превышается максимально допустимое количество дескрипторов файлов, открытых одновременно в одном процессе.

[ENFILE]

переполнение системной таблицы файлов.

[EROFS]

указанный файл расположен в файловой системе, доступной только на чтение, а открывается на запись или чтение/запись.