Категории
Самые читаемые
ChitatKnigi.com » 🟢Компьютеры и Интернет » Интернет » UNIX — универсальная среда программирования - Керниган Брайан Уилсон

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

Читать онлайн UNIX — универсальная среда программирования - Керниган Брайан Уилсон
1 ... 76 77 78 79 80 81 82 83 84 ... 187
Перейти на страницу:

Шрифт:

-
+

Интервал:

-
+

Закладка:

Сделать

   fputs(buf, stdout);

  else {

   buf[strlen(buf)-1] = '';

   fputs(buf, stdout);

   fflush(stdout);

   ttyin();

   lines = 0;

  }

}

Мы использовали здесь BUFSIZ, который определен в <stdio.h> как размер буфера входного потока. Функция fgets(buf, size, fp) выбирает следующую строку входного потока из fp до символа перевода строки (включая его) в буфер и добавляет завершающий символ . Копируется на более 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

1 ... 76 77 78 79 80 81 82 83 84 ... 187
Перейти на страницу:
Открыть боковую панель
Комментарии
Jonna
Jonna 02.01.2025 - 01:03
Страстно🔥 очень страстно
Ксения
Ксения 20.12.2024 - 00:16
Через чур правильный герой. Поэтому и остался один
Настя
Настя 08.12.2024 - 03:18
Прочла с удовольствием. Необычный сюжет с замечательной концовкой
Марина
Марина 08.12.2024 - 02:13
Не могу понять, где продолжение... Очень интересная история, хочется прочесть далее
Мприна
Мприна 08.12.2024 - 01:05
Эх, а где же продолжение?