How to synchronize input with output on terminal?

I am writing a linux shell for a custom scripting language, and I want to print "..." before each subsequent line that the user enters for a single statement, with the first line having "→>", then waiting for input. The following is an example:

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

I am reading a line with fgets , and after I have completely read it, I type "..." and repeat using another call to fgets . This is great for moderately fast interactive input. But if I paste the code containing the new lines into the terminal, then I get the following

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

"..." is displayed too late, even if I fflush call after I print them to stdout . Does anyone know if there is anything special to make this work?

+4
source share
2 answers

If you disable the echo (see stty(1) -echo ) for the terminal, then you have full control over when the input is printed on the screen.

My assumption is that the insertion causes all lines to be written to the terminal at once, and your program will never get the opportunity to send output to the terminal when necessary. Thus, if you turn off the echo and print out user input as you type it, you can perform special processing when you see newline characters.

You can see that the irb program does something very similar by running strace on it:

 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 
+1
source

There is actually no easy way to do this with stdio - you will need to use something like ncurses to control the terminal. The problem is that when copying and pasting multiple lines, such as all, they all fall into the stdin read buffer by one by calling read(2) , so stdout is unable to intervene and print intermediate requests.

0
source

Source: https://habr.com/ru/post/1344209/


All Articles