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
даже без системных вызовов.
Интерфейс, с которым вам, как программисту, возможно, доведется работать, представляет собой набор оболочек библиотеки С для системных вызовов. В оставшейся части этой книги под системным вызовом будет подразумеваться функция оболочки С, которая используется для реализации системного вызова, а не тот неуклюжий интерфейс, который скрывает библиотека С.
Большинство, но не все, системные вызовы объявлены в
. Фактически файл
представляет собой универсальное вместилище практически для всех системных вызовов. Чтобы определить, какие включаемые файлы нужно использовать, обычно нужно обратиться к системным 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
, обозначая успех, оба эти случая идентичны. В своем коде можете выбрать то, что вам больше подходит. Будьте готовы к тому, что столкнетесь с этими и другими способами обработки в чужих кодах.
Существует множество общих кодов ошибок, для которых вы вполне могли наблюдать сообщения. Некоторые из этих сообщений могут сбивать с толку. Без знаний о том, что можно делать в Linux-системе, трудно понять ошибки, которые могут возникать в процессе работы. Внимательно прочитайте приведенный ниже список.