Книга: Разработка приложений в среде Linux. Второе издание
9.2.2. Коды возврата системных вызов
9.2.2. Коды возврата системных вызов
Коды возврата, зарезервированные для всех системных вызовов — это универсальные коды возврата ошибок, представленные небольшими отрицательными числами. Библиотека С проверяет наличие ошибок каждый раз, когда происходит системный вызов. При возникновении ошибки библиотека помещает значение ошибки в глобальную переменную errno
[15]. В большинстве случаев все, что вам необходимо при проверке ошибки — посмотреть, отрицательный ли код возврата. Коды ошибок определены в <errno.h>
, и errno
можно сравнить с любым номером ошибки из этого файла, после чего обработать ее специальным образом.
Переменная errno
используется и в другом случае. Библиотека С предлагает три способа получения строк, предназначенных для описания возникшей ошибки.
perror()
Печатает сообщение об ошибке. Передайте в функцию строку с информацией о том, что код намеревался предпринять.
if ((file = open(DB_PATH, O_RDONLY)) < 0) {
perror("не удается открыть файл базы данных");
}
Функция perror()
выведет сообщение, описывающее возникшую ошибку, а также объяснение того, что код собирался делать:
не удается открыть файл базы данных: No such file or directory
Обычно неплохо делать свои аргументы для perror()
уникальными на протяжении всей программы, в результате при получении сообщений об ошибках из perror()
вы будете точно знать, откуда начинать поиск. Обратите внимание, что в строке, передаваемой perror()
, нет символа новой строки. Его передавать не нужно — функция сама его выведет.
strerror()
Возвращает статически распределенную строку, описывающую ошибку с номером, передаваемым в единственном аргументе. Это можно использовать при построении, например, своей собственной версии perror()
.
if ((file = open(DB_PATH, O_RDONLY) ) < 0) {
fprintf(stderr,
"не удается открыть файл базы данных %s, %sn",
DB_PATH, strerror(errno));
}
sys_errlist
He очень хорошая альтернатива strerror()
. sys_errlist
— это массив размером sysnerr
указателей на статические, доступные только для чтения символьные строки, которые описывают ошибки. Попытка записи в эти строки приводит к нарушению сегментации и сбросу дампа ядра.
if ((file = open(DB_PATH, O_RDONLY)) < 0) {
if (errno < sys_nerr) {
fprintf(stderr,
"не удается открыть файл базы данных %s, %sn",
DB_PATH, sys_errlist[errno]);
}
}
Этот массив не является ни стандартным, ни переносимым, и упоминается здесь лишь потому, что вы можете столкнуться с кодом, от него зависящим. Заменив такой код вызовом функции strerror()
, вы получите существенный выигрыш.
Если вы не собираетесь использовать errno
сразу же после генерации ошибки, сохраните ее копию. Любая библиотечная функция может установить errno
в любое значение, поскольку в ней могут присутствовать системные вызовы, о которых вы даже не подозреваете. А некоторые библиотечные функции могут устанавливать errno
даже без системных вызовов.
- 9.2. Системные вызовы
- 9.2.1. Ограничения системных вызовов
- 9.2.4. Общие коды возврата ошибок
- Модификация системных таблиц
- Вызов хранимых процедур InterBase с использованием стандартного синтаксиса ODBC
- Системные вызовы и драйверы устройств
- Определение необходимого системного вызова
- Системные вызовы управления процессорной привязкой
- Приложение 10. Коды ошибок
- Вызовы функций
- Другие системные вызовы для управления файлами
- Вызов pipe