Чтение онлайн

на главную

Жанры

Разработка приложений в среде Linux. Второе издание

Троан Эрик В.

Шрифт:

Переменная

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, %s\n",

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, %s\n",

DB_PATH, sys_errlist[errno]);

 }

}

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

strerror
, вы получите существенный выигрыш.

Если вы не собираетесь использовать

errno
сразу же после генерации ошибки, сохраните ее копию. Любая библиотечная функция может установить
errno
в любое значение, поскольку в ней могут присутствовать системные вызовы, о которых вы даже не подозреваете. А некоторые библиотечные функции могут устанавливать
errno
даже без системных вызовов.

9.2.3. Использование системных вызовов

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

Большинство, но не все, системные вызовы объявлены в

<unistd.h>
. Фактически файл
<unistd.h>
представляет собой универсальное вместилище практически для всех системных вызовов. Чтобы определить, какие включаемые файлы нужно использовать, обычно нужно обратиться к системным man-страницам. Хотя описания функций на man-страницах зачастую весьма лаконичны, там можно найти точные указания о том, какой файл должен быть включен для использования функции.

Есть одна особенность, свойственная системам Unix. Системные вызовы документированы в отдельном разделе man-страниц для библиотечных функций, и вы будете использовать библиотечные функции для доступа к системным вызовам. Там, где библиотечные функции отличаются от системных вызовов, предусмотрены отдельные man- страницы. Это не вызывало бы проблем, однако практически всегда требуется читать страницу, описывающую библиотечную функцию, номер которой больше номера страницы с описанием соответствующего системного вызова. Ввиду того, что man-страницы выводятся, начиная с меньших номеров, приходится проделывать лишнюю работу.

Простого указания номера раздела недостаточно. Системные вызовы, которые помещены в минимальные функции-оболочки из библиотеки С, не документированы как часть библиотеки, следовательно команда

man 3 функция
не найдет их. Для того чтобы убедиться, что вы прочли всю необходимую для вас информацию, вначале взгляните на man-страницу, не указывая раздел. Если это раздел 2 на man-странице, посмотрите, есть ли там раздел 3 с таким же именем. Если открывается раздел 1 man-страницы, как это часто случается, внимательно просмотрите разделы 2 и 3.

К счастью, существует другой способ решения такой проблемы. Многие версии программы

man
, включая используемую в системах Linux, позволяют указывать альтернативный путь поиска man-страниц. Прочтите man-страницу о самой программе
man
, чтобы определить, поддерживается ли в вашей версии
man
переменная окружения
MANSECT
и аргумент
– S
. Если переменная поддерживается, можно установить
MANSECT
в что-нибудь вроде
3:2:1:4:5:6:7:8:tcl:n:l:p:о
. Просмотрите в файле конфигурации
man
(в большинстве систем Linux это
/etc/man.config
) текущую настройку
MANSECT
.

Большинство системных вызовов возвращает

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

if (ioctl(fd, FN, data)) {

 /* обработка ошибки на основе errno */

}

Часто встречается следующая форма:

if (ioctl(fd, FN, data) < 0) {

 /* обработка ошибки на основе errno */

}

Для системных вызовов, которые возвращают

0
, обозначая успех, оба эти случая идентичны. В своем коде можете выбрать то, что вам больше подходит. Будьте готовы к тому, что столкнетесь с этими и другими способами обработки в чужих кодах.

9.2.4. Общие коды возврата ошибок

Существует множество общих кодов ошибок, для которых вы вполне могли наблюдать сообщения. Некоторые из этих сообщений могут сбивать с толку. Без знаний о том, что можно делать в Linux-системе, трудно понять ошибки, которые могут возникать в процессе работы. Внимательно прочитайте приведенный ниже список.

Поделиться:
Популярные книги

Светлая ведьма для Темного ректора

Дари Адриана
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Светлая ведьма для Темного ректора

Дайте поспать! Том II

Матисов Павел
2. Вечный Сон
Фантастика:
фэнтези
постапокалипсис
рпг
5.00
рейтинг книги
Дайте поспать! Том II

Последний попаданец 12: финал часть 2

Зубов Константин
12. Последний попаданец
Фантастика:
фэнтези
юмористическое фэнтези
рпг
5.00
рейтинг книги
Последний попаданец 12: финал часть 2

Решала

Иванов Дмитрий
10. Девяностые
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Решала

Истребители. Трилогия

Поселягин Владимир Геннадьевич
Фантастика:
альтернативная история
7.30
рейтинг книги
Истребители. Трилогия

Попаданка для Дракона, или Жена любой ценой

Герр Ольга
Любовные романы:
любовно-фантастические романы
7.17
рейтинг книги
Попаданка для Дракона, или Жена любой ценой

Беглец. Второй пояс

Игнатов Михаил Павлович
8. Путь
Фантастика:
фэнтези
героическая фантастика
боевая фантастика
5.67
рейтинг книги
Беглец. Второй пояс

Черный Маг Императора 4

Герда Александр
4. Черный маг императора
Фантастика:
юмористическое фэнтези
попаданцы
аниме
5.00
рейтинг книги
Черный Маг Императора 4

Боги, пиво и дурак. Том 3

Горина Юлия Николаевна
3. Боги, пиво и дурак
Фантастика:
фэнтези
попаданцы
5.00
рейтинг книги
Боги, пиво и дурак. Том 3

Волк: лихие 90-е

Киров Никита
1. Волков
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Волк: лихие 90-е

Рота Его Величества

Дроздов Анатолий Федорович
Новые герои
Фантастика:
боевая фантастика
8.55
рейтинг книги
Рота Его Величества

На изломе чувств

Юнина Наталья
Любовные романы:
современные любовные романы
6.83
рейтинг книги
На изломе чувств

Дракон

Бубела Олег Николаевич
5. Совсем не герой
Фантастика:
фэнтези
попаданцы
9.31
рейтинг книги
Дракон

Кодекс Крови. Книга IV

Борзых М.
4. РОС: Кодекс Крови
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Кодекс Крови. Книга IV