Читать книгу 📗 "Linux программирование в примерах - Роббинс Арнольд"
Многие системы предоставляют также другие значения ошибок, а в более старых системах может не быть всех перечисленных значений ошибок. Полный список следует проверить с помощью справочных страниц intro(2) и errno(2) для локальной системы.
ЗАМЕЧАНИЕ.
errnoСначала мы используем
errnoperror()#include <stdio.h> /* ISO С */void perror(const char *s);Функция
perror()errnoif (some_system_call(param1, param2) < 0) { perror("system call failed"); return 1;}Мы предпочитаем функцию
strerror()#include <string.h> /* ISO С */char *strerror(int errnum);strerror()fprintf()if (some_system_call(param1, param2) < 0) { fprintf(stderr, "%s: %d, %d: some_system_call failed: %sn", argv[0], param1, param2, strerror(errno)); return 1;}По всей книге вы увидите множество примеров использования обеих функций.
4.3.2. Стиль сообщения об ошибках
Для использования в сообщениях об ошибках С предоставляет несколько специальных макросов. Наиболее широкоупотребительными являются
__FILE____LINE____func__if (some_system_call(param1, param2) < 0) { fprintf(stderr, "%s: %s (%s %d): some_system_call(%d, %d) failed: %sn", argv[0], __func__, __FILE__, __LINE__, param1, param2, strerror(errno)); return 1;}Здесь сообщение об ошибке включает не только имя программы, но также и имя функции, имя исходного файла и номер строки. Полный список идентификаторов, полезных для диагностики, приведен в табл. 4.2.
Таблица 4.2. Диагностические идентификаторы C99
| Идентификатор | Версия С | Значение |
|---|---|---|
__DATE__ | C89 | Дата компиляции в виде «Mmm nn yyyy |
__FILE_ | Оригинальная | Имя исходного файла в виде «program.c |
__LINE__ | Оригинальная | Номер строки исходного файла в виде 42 |
__TIME__ | C89 | Время компиляции в виде «hh:mm:ss |
__func__ | C99 | Имя текущей функции, как если бы было объявлено const char __func__[] = "name" |
Использование
__FILE____LINE__Сегодня, хотя системы GNU/Linux поставляются с исходными кодами, указанный исходный код часто не устанавливается по умолчанию. Поэтому использование этих идентификаторов для сообщений об ошибках не представляет дополнительной ценности. GNU Coding Standards даже не упоминает их.
4.4. Ввод и вывод
Все операции Linux по вводу/выводу осуществляются посредством дескрипторов файлов. Данный раздел знакомит с дескрипторами файлов, описывает, как их получать и освобождать, и объясняет, как выполнять с их помощью ввод/вывод.
4.4.1. Понятие о дескрипторах файлов
Дескриптор файла является целым значением. Действительные дескрипторы файлов начинаются с 0 и растут до некоторого установленного системой предела. Эти целые фактически являются индексами таблицы открытых файлов для каждого процесса (Таблица поддерживается внутри операционной системы; она недоступна запущенным программам.) В большинстве современных систем размеры таблиц большие. Команда '
ulimit -n$ <b>ulimit -n</b>1024Из С максимальное число открытых файлов возвращается функцией
getdtablesize()#include <unistd.h> /* Обычный */int getdtablesize(void);Следующая небольшая программа выводит результат работы этой функции:
/* ch04-maxfds.с --- Демонстрация getdtablesize(). */