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

Мы использовали здесь BUFSIZ, который определен в stdio.h как размер буфера входного потока. Функция fgets(buf, size, fp) выбирает следующую строку входного потока из fp до символа перевода строки (включая его) в буфер и добавляет завершающий символ \0. Копируется на более size - 1 символов. По достижении конца файла возвращается NULL. (Конструкция fgets оставляет желать лучшего: она возвращает buf вместо счетчика символов и, кроме того, выдает предупреждение о том, что входная строка была слишком длинной. Символы не потеряны, но вы должны взглянуть на buf, чтобы понять, что в самом деле случилось.)

Функция strlen возвращает длину строки, поэтому мы можем отбросить завершающий символ перевода строки последней входной строки. После вызова fputs(buf, fp) строка buf записана в файл fp. При вызове fflush в конце страницы происходит вывод буферизованного выходного текста.

Считывание ответа пользователя в конце каждой страницы возложено на функцию ttyin. Функция ttyin не может читать стандартный входной поток, тогда как p должна выполняться, даже если входной поток поступает из файла или конвейера. Чтобы справиться с этим, программа открывает файл /dev/tty, которому поставлен в соответствие пользовательский терминал при любом переключении стандартного входного потока. Приведенная ниже функция ttyin возвращает первую букву ответа, но здесь это свойство не используется.

ttyin /* process response from /dev/tty (version 1) */

{

 char buf[BUFSIZ];

 FILE *efopen;

 static FILE *tty = NULL;

 if (tty == NULL)

  tty = efopen("/dev/tty", "r");

 if (fgets(buf, BUFSIZ, tty) == NULL || buf[0] == 'q')

  exit(0);

 else /* ordinary line */

  return buf[0];

}

Указатель на файл devtty описан как статический, так что его значение сохраняется от одного вызова ttyin до другого; файл /dev/tty открывается только при первом вызове.

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

$ p -n...

Она печатает порции по n строк. Для этого требуется лишь добавить несколько знакомых вам операторов в начале main:

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

...

int i, pagesize = PAGESIZE;

progname = argv[0];

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

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

 argc--;

 argv++;

}

Функция atoi превращает строку символов в целое число (см. справочное руководство по atoi(3)).

Еще одно средство временно остановить вывод на экран в конце каждой страницы, чтобы выполнить какую-либо иную команду. По аналогии с ed и многими другими программами, если пользователь печатает строку, начинающуюся восклицательным знаком, остальная часть строки воспринимается как команда и передается shell для выполнения. Данное средство также тривиально, поскольку для этой цели предусмотрена функция system(3), речь о которой пойдет ниже. Модифицированная версия ttyin такова:

ttyin /* process response from /dev/tty (version 2) */

{

 char buf[BUFSIZ];

 FILE *efopen;

 static FILE *tty = NULL;

 if (tty == NULL)

  tty = efopen("/dev/tty", "r");

 for (;;) {

  if (fgets(buf,BUFSIZ,tty) == NULL || buf[0] == 'q')

   exit(0);

  else if (buf[0] == '!') {

   system(buf+1); /* BUG here */

   printf("!\n");

  else /* ordinary line */

   return buf[0];

 }

}

К сожалению, эта версия ttyin имеет серьезный недостаток. Команда, запущенная с помощью system, получает стандартный входной поток от p, так что если p читает из программного канала или файла, их входные потоки могут мешать друг другу:

$ cat /etc/passwd | p -1

root:3d.fHR5KoB.3s:0:l:S.User:/:!ed Вызвать ed из p

? ed читает /etc/passwd

! … запутывается и завершается

Перейти на страницу:

Похожие книги

1001 совет по обустройству компьютера
1001 совет по обустройству компьютера

В книге собраны и обобщены советы по решению различных проблем, которые рано или поздно возникают при эксплуатации как экономичных нетбуков, так и современных настольных моделей. Все приведенные рецепты опробованы на практике и разбиты по темам: аппаратные средства персональных компьютеров, компьютерные сети и подключение к Интернету, установка, настройка и ремонт ОС Windows, работа в Интернете, защита от вирусов. Рассмотрены не только готовые решения внезапно возникающих проблем, но и ответы на многие вопросы, которые возникают еще до покупки компьютера. Приведен необходимый минимум технических сведений, позволяющий принять осознанное решение.Компакт-диск прилагается только к печатному изданию книги.

Юрий Всеволодович Ревич

Программирование, программы, базы данных / Интернет / Компьютерное «железо» / ОС и Сети / Программное обеспечение / Книги по IT
Секреты приложений Google
Секреты приложений Google

Даже продвинутые пользователи Интернета не подозревают о тех огромных возможностях, которые предоставляют сервисы Google. Автор рассказывает о таких «секретах» сервисов, которые просто немедленно хочется использовать! Создавать сайты и презентации, бродить по улочкам Парижа, изучать звездное небо – все это доступно каждому, кто сидит у экрана монитора и имеет доступ в Интернет. Книга научит вас работать с веб-приложениями и тысячекратно увеличить свои возможности с помощью новейших технологий. Она написана легким, доступным языком и не требует от читателя наличия каких-либо специальных знаний. Книга содержит множество примеров, иллюстраций и будет полезна всем, кто не стоит на месте и стремится сделать свою жизнь более насыщенной и интересной.

Денис Балуев , Денис Игоревич Балуев

Программирование, программы, базы данных / Интернет / Программное обеспечение / Книги по IT
Wi-Fi: Все, что Вы хотели знать, но боялись спросить
Wi-Fi: Все, что Вы хотели знать, но боялись спросить

Жизнь современного человека — это движение. Мобильность для нас становится одним из самых важных моментов для работы, для общения, для жизни. Многие из нас сейчас уже не представляют жизнь без сотовых телефонов, которые из средства роскоши превратились в предмет, без которого жизнь современного человека стала просто немыслима. Многие уже оценили все преимущества Bluetooth, GPRS. Эти устройства превратили наши телефоны из средств связи в незаменимых помощников в работе. К сожалению, один из самых главных недостатков этих беспроводных технологий — малый радиус действия и низкая скорость передачи данных, что сейчас становится очень важным фактором для всех нас. Поэтому к нам на помощь приходит активно развивающийся во всем мире и в России стандарт Wi-Fi. Особенно радует, что в крупных городах России, особенно в Москве и Санкт-Петербурге, начинается массовое внедрение беспроводных сетей Wi-Fi в публичных местах (так называемых Hot Spot) — отелях, аэропортах, ресторанах, торговых центрах и кафе.Что же такое Wi-Fi? Очередной мыльный пузырь IT-индустрии, который изо всех сил надувают производители и поставщики телекоммуникационного оборудования или новая технология, призванная в очередной раз изменить наш привычный мир, как это случилось когда-то с появлением Интернет и сотовой связи?

А К Щербаков , А. К. Щербаков

Компьютерное 'железо' (аппаратное обеспечение), цифровая обработка сигналов / Интернет / Компьютерное «железо» / Книги по IT