Linux программирование в примерах | страница 73



Unix вместо попытки открыть файл с именем читает стандартный ввод. Вдобавок, >cat читает стандартный ввод, когда нет аргументов. >ch04-cat реализует оба этих поведения. Условие '>argc == 1' (строка 27) истинно, когда нет аргументов имени файла; в этом случае >main() передает «>-» функции >process(). В противном случае, >main() перечисляет аргументы, рассматривая их как файлы, которые необходимо обработать. Если один из них окажется «>-», программа обрабатывает стандартный ввод.

Если >process() возвращает ненулевое значение, это означает, что случилась какая- то ошибка. Ошибки подсчитываются в переменной >errs (строки 28 и 31). Когда >main() завершается, она возвращает 0, если не было ошибок, и 1, если были (строка 33). Это довольно стандартное соглашение, значение которого более подробно обсуждается в разделе 9.1.5.1 «Определение статуса завершения процесса».

Структура, представленная в >main(), довольно общая: >process() может делать с файлом все, что мы захотим. Например (игнорируя особый случай «>-»), process() также легко могла бы удалять файлы вместо их объединения!

Прежде чем рассмотреть функцию >process(), нам нужно описать, как представлены ошибки системных вызовов и как осуществляется ввод/вывод. Сама функция >process() представлена в разделе 4.4.3 «Чтение и запись».

4.3. Определение ошибок

«Если неприятность может произойти, она случается»

- Закон Мерфи -

«Будь готов»

- Бойскауты -

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

Основные системные вызовы Linux почти всегда возвращают при ошибке -1 и 0 или положительное значение при успехе. Это дает возможность узнать, была операция успешной или нет:

>int result;

>result = some_system_call(param1, param2);

>if (result < 0) {

> /* ошибка, что-нибудь сделать */

>} else

> /* все нормально, продолжить */

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

>#include /* ISO С */


>extern int errno;

Хотя сама