Как синхронизировать ввод с выводом на терминале? - PullRequest
4 голосов
/ 18 марта 2011

Я пишу оболочку linux для пользовательского языка сценариев и хочу напечатать «...» перед каждой последующей строкой, которую пользователь вводит для отдельного оператора, причем первая строка имеет «>> > "распечатано, то жду ввода. Ниже приведен пример:

>>> void f() {
...  "this is a test"
... }
>>> 

Я читаю строку с fgets, и после того, как я полностью прочитал ее, я печатаю «...» и повторяю, используя другой вызов fgets. Это отлично работает для умеренно быстрого интерактивного ввода. Но если я вставлю код, содержащий символы новой строки, в терминал, я получу следующее

>>> void f() {
 "this is a test"
}
... ... >>> 

«...» печатаются слишком поздно, хотя я посылаю вызов fflush после того, как напечатаю их на stdout. Кто-нибудь знает, есть ли что-то особенное, чтобы сделать эту работу?

Ответы [ 2 ]

1 голос
/ 18 марта 2011

Если вы отключите эхо (см. stty(1) -echo) для терминала, тогда вы полностью контролируете, когда ввод выводится на экран.

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

Вы можете увидеть, что программа irb делает нечто очень похожее,под управлением strace на нем:

ioctl(0, SNDCTL_TMR_TIMEBASE or TCGETS, {B38400 opost isig icanon echo ...}) = 0
...
ioctl(0, SNDCTL_TMR_STOP or TCSETSW, {B38400 opost isig -icanon -echo ...}) = 0
0 голосов
/ 18 марта 2011

На самом деле нет простого способа сделать это с помощью stdio - вам нужно использовать что-то вроде ncurses для управления терминалом.Проблема в том, что когда вы копируете и вставляете несколько таких строк, все они помещаются в буфер чтения стандартного ввода за один вызов read(2), поэтому стандартный вывод не может вмешаться и напечатать промежуточные запросы.

...