Категории
Самые читаемые
💎Читать книги // БЕСПЛАТНО // 📱Online » Компьютеры и Интернет » Программное обеспечение » UNIX — универсальная среда программирования - Брайан Керниган

Читаем без скачивания UNIX — универсальная среда программирования - Брайан Керниган

Читать онлайн UNIX — универсальная среда программирования - Брайан Керниган

Шрифт:

-
+

Интервал:

-
+

Закладка:

Сделать
1 ... 51 52 53 54 55 56 57 58 59 ... 103
Перейти на страницу:

}

ncopy(fin, n, fout) /* copy n lines from fin to fout */

 FILE *fin, *fout;

{

 char buf[BUFSIZ];

 while (n-- > 0) {

  if (fgets(buf, sizeof buf, fin) == NULL)

   return;

  fputs(buf, fout);

 }

}

Программа idiff, если ее прервать, оставляет несколько файлов, хранящихся в /tmp. В следующей главе мы покажем, как перехватывать прерывания, чтобы убрать временные файлы, подобные использованным здесь.

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

Упражнение 6.13

Добавьте команду q к idiff: ответ q с автоматически выберет остаток от альтернатив '<'; q > возьмет все оставшееся от альтернатив '>'.

Упражнение 6.14

Модифицируйте idiff так, чтобы некоторые аргументы idiff передавались к diff; -b и -h вероятные кандидаты. Выполните еще одну модификацию idiff, позволяющую определять другой редактор, как в команде

$ idiff -е другой редактор file1 file2

Как взаимодействуют эти две модификации?

Упражнение 6.15

Измените idiff, чтобы использовать popen и pclose вместо временного файла для выходного потока diff. Как это скажется на сложности и скорости выполнения программы?

Упражнение 6.16

Если один из аргументов diff -каталог, то в этом каталоге идет поиск файла с именем, заданным другим аргументом. Но если вы попробуете сделать то же самое с idiff, то она почему-то собьётся. Объясните, что в данном случае происходит, и исправьте дефект.

6.9 Доступ к среде

Из Си-программы легко "добраться" до переменных в среде shell, что можно использовать для упрощения адаптации программы к окружению. Допустим, например, что размер экрана вашего терминала больше обычного (24-строкового). Чего вы сможете добиться, применив p и воспользовавшись преимуществами своего терминала? Необходимость определять размер экрана всякий раз, когда вы вводите p, надоедает:

$ p -36...

Вы могли бы всегда вставлять файл shell в свой bin:

$ cat /usr/you/bin/p

exec /usr/bin/p -36 $*

$

Третье решение модифицировать p, чтобы использовать те переменные среды, которые определяют свойства вашего терминала. Предположим, что вы определили переменную PAGESIZE в своем .profile:

PAGESIZE=36

export PAGESIZE

Функция getenv("var") ищет в среде командную переменную var и возвращает ее значение как строку символов или NULL, если переменная не определена. При наличии getenv легко модифицировать p: достаточно лишь добавить пару описаний и вызов getenv к началу основной программы.

/* p: print input in chunks (version 3) */

...

char *p, *getenv();

progname = argv[0];

if ((p=getenv("PAGESIZE")) != NULL)

 pagesize = atoi(p);

if (argc > 1 && argv[1][0] == '-') {

 pagesize = atoi(&argv[1][1]);

 argc--;

 argv++;

}

Флаги обрабатываются вслед за переменной среды, так что любой явно заданный размер страницы в конце концов заменит неявно заданный.

Упражнение 6.17

Модифицируйте idiff так, чтобы она искала в среде имя редактора, который следует применить. Измените 2, 3 и т.д., чтобы использовать PAGESIZE.

Историческая и библиографическая справка

Стандартная библиотека ввода-вывода была разработана Д. Ритчи вслед за переносимой библиотекой ввода вывода М. Леска. Оба пакета имели целью предоставить пользователю стандартные средства, чтобы можно было переносить программы без изменений с UNIX в другие системы.

Наша версия p основана на программе Г. Спенсера. Программа adb написана С. Борном, sdb Г. Катцефом, a lint С. Джонсоном.

Программа idiff в общих чертах построена на базе программы, первоначально написанной Дж. Маранзано. Сама diff детище Д. МакИлроя и основана на алгоритме, созданном независимо Г. Стоуном и В. Хантом совместно с Т. Шиманским (Hunt J. W., Szymanski Т. G. "A fast algorithm for computing longest common subsequences." CACM, May 1977.) Алгоритм "diff" описан в работе M. Д. МакИлроя и Д. В. Ханта "An algorithm for differential file comparison" (Bell Labs Computing Science Technical Report 41, 1976). В заключение приведем слова МакИлроя: "Я опробовал три различных алгоритма, прежде чем выбрал окончательный вариант. По сути diff позволяет не только хорошо понять программу, но и пересматривать ее до тех пор, пока она не станет правильной".

Глава 7

Системные вызовы в UNIX

В настоящей главе мы рассмотрим самый низкий уровень взаимодействия с операционной системой UNIX системные вызовы. Они являются входами в ядро. Эти средства предоставляются операционной системой; все остальные средства построены на их основе.

Материал главы охватывает несколько важных областей. К ним относится прежде всего система ввода-вывода, являющаяся основной для функций типа fopen и putс. Речь пойдет также о файловой системе, в частности о каталогах и индексных дескрипторах. Затем мы обсудим процессы, т.е. как запускать задачи из программы, после чего поговорим о сигналах и прерываниях: что происходит, когда вы нажимаете клавишу DELETE, и как такую ситуацию должным образом обработать в программе.

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

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

7.1 Ввод-вывод низкого уровня

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

Дескрипторы файлов

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

В самом общем случае, прежде чем читать или писать файл, необходимо сообщить системе о вашем намерении открыть файл. Если вы собираетесь писать в файл, может быть, его необходимо и создать. Система проверяет ваше право сделать это (существует ли файл и есть ли у вас разрешение на доступ к нему?), и при положительном результате проверки возвращает неотрицательное целое, называемое дескриптором файла. Всякий раз, когда нужно выполнить ввод-вывод через файл, для его идентификации вместо имени используется дескриптор файла. Вся информация об открытом файле поддерживается системой. Ваша программа ссылается на файл только через дескриптор файла. Указатель на FILE, как отмечалось в гл. 6, является ссылкой на структуру, которая наряду с прочим содержит дескриптор файла: макрокоманда fileno(fp), определенная в <stdio.h>, возвращает дескриптор файла.

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

При переключении ввода-вывода на файлы или программные каналы (к ним или от них) shell изменяет назначение терминала по умолчанию для дескрипторов файлов 0 и 1. Обычно дескриптор файла 2 закрепляется за терминалом, так что сообщения об ошибках могут поступать на него. Использование символики shell, такой, как 2>filename и 2>&1, вызовет переназначение файла, присвоенного по умолчанию, но при этом присвоение файлов меняется в shell, а не программой. (Программа сама может переназначить их впоследствии, если потребуется, что, правда, бывает редко.)

1 ... 51 52 53 54 55 56 57 58 59 ... 103
Перейти на страницу:
На этой странице вы можете бесплатно скачать UNIX — универсальная среда программирования - Брайан Керниган торрент бесплатно.
Комментарии