Обработке ошибок уделяется большое значение в UNIX, так как написание надежных и устойчивых программ, особенно для многопользовательских систем, является весьма важным.
Обычно в случае возникновения ошибки системные вызовы возвращают -1 и устанавливают значение переменной errno, указывающее возникновение ошибки. Библиотечные функции, как правило, значение errno не устанавливают, а код возврата различен для различных функций. Переменная errno не обнуляется следующим нормально завершившимся системным вызовом, следовательно эту переменную следует анализировать сразу же после системного вызова, который завершился с ошибкой.
Имеются также две функции, помогающие сообщить причину ошибочной ситуации.
external int errno;
#include <string.h>
char *strerror (int enum);
#include <errno.h>
#include <stdio.h>
void perror (char *s);
main (int argc, char *argv[ ])
{
fprintf(stderr, “ENOMEM:%s\n”, strerror (ENOMEM));
errno = ENOEXEC;
perror (argv[0]);
}
Функция strerror принимает в качестве аргумента номер ошибки и возвращает указатель на строку, содержащую сообщение о причине ошибочной ситуации.
|
|
Функция perror выводит в стандартный поток сообщений об ошибках информацию об ошибочной ситуации, основываясь на значении переменной errno. Строка s, передаваемая функции в качестве аргумента, предваряет сообщение об ошибке и может содержать дополнительную информацию, например название функции, в которой произошла ошибка.
Имеется условное обозначение большого числа ошибочных ситуаций, при которых они могут обнаруживаться и обрабатываться. Некоторые из них приведены ниже.
№ | Ошибочная ситуация | Примечание |
E2BIG | Размер списка аргументов, переданных системному вызову exec плюс размер экспортируемых переменных окружения превышает максимально допустимое число байт (ARG_MAX). | |
EACCESS | Попытка доступа к файлу с недостаточными правами доступа для данного класса. | |
EAGAIN | Превышен предел использования некоторого ресурса, например переполнена таблица процессов. | |
EBADF | Попытка операции с файловым дескриптором, не адресующим никакой файл или попытка работы с файлом на недопустимую операцию (например, файл открыт на чтение, а попытка записи). | |
EBADFD | Файловый дескриптор не адресует открытый файл или попытка выполнения операции чтения с файловым дескриптором, полученным при открытии только на запись. | |
EBUSY | Попытка монтирования устройства (файловой системы), которое уже примонтировано; попытка размонтировать файловую систему, имеющую открытые файлы; попытка обращения к недоступным ресурсам. | |
ECHILD | Вызов функции wait процессом, не имеющим дочерних процессов или повторный вызов wait для процесса, для которого этот вызов уже был сделан. | |
EDQUOT | Зарезервирован | |
EEXIST | Имя существующего файла использовано в недопустимом контексте, например, попытка создания символической связи с именем уже существующего файла. | |
EFAULT | Аппаратная ошибка при попытке использования системой аргумента функции, например, в качестве указателя передан недопустимый адрес. | |
EFBIG | Размер файла превысил установленное ограничение RLIMIT_FSIZE или максимально допустимый размер для данной файловой системы. | |
EINTR | Получение асинхронного сигнала (SIGINT или SIGQUIT) во время обработки системного вызова.Если выполнение процесса будет продолжено после обработки сигнала, прерванный системный вызов завершится с этой ошибкой. | |
EINVAL | Передача неверного аргумента системному вызову. | |
EIO | Ошибка ввода-вывода физического устройства. | |
EISDIR | Попытка операции, недопустимой для каталогов. | |
EMFILE | Число открытых файлов для процесса превысило максимально допустимое значение. | |
ENAMETOOLONG | Длина имени файла, включая путь, превысило максимально допустимое значение. | |
ENFILE | Переполнение файловой таблицы. | |
ENODEV | Попытка недопустимой операции для устройства. | |
ENOENT | Файл с указанным именем не существует или отсутствует каталог, указанным в полном имени файла. | |
ENOEXEC | Попытка запуска на выполнение файла, который имеет права на выполнение, но не является файлом допустимого исполняемого формата | |
ENOMEM | Размер запрашиваемой памяти при запуске программы превысил максимально возможный в системе. | |
ENOTDIR | При задании имени каталога в операции, предусматривающей в качестве аргумента имя каталога, было указано имя файла другого типа. | |
EPIPE | Попытка записи в канал, для которого не существует процесса, принимающего данные. В этой ситуации процессу обычно направляется сигнал, ошибка возвращается при игнорировании сигнала. | |
ESRCH | Процесс с указанным PID не существует. |
Программистам также предоставляется большой набор функций общего назначения, которые не являются точками входа в операционную систему, хотя в процессе выполнения многие из них выполняют системные вызовы (например, функция printf записывает данные в файл, используя системный вызов read). Библиотечные функции, хранящиеся в стандартных библиотеках вместе с системными вызовами, составляют основу среды программирования UNIX.
|
|
При разработке программ важное значение имеют файлы заголовков, где описаны значения большого количества констант и т.д.