2

I was trying to read input from the terminal using read() in a while loop as a condition, but the code doesn't get executed until the loop ends.

Here is my code:

#include<unistd.h>
int main(void)
{
    char ch;
    while(read(STDIN_FILENO,&ch,1) == 1 && ch != 'q')
    {
        printf("success");
    }
    return 0;
}

it gives me the output :

t
fgr
vr

q
successsuccesssuccesssuccesssuccesssuccesssuccesssuccesssuccesssuccess

Even when I try to normally read data, the unread data in the buffer ends up like this.

code:

#include<unistd.h>
int main(void)
{
    char ch;
    read(STDIN_FILENO,&ch,1);
    return 0;
}

output in terminal

user1@lap:~/Desktop$ ./program2e3
ted
pradeep@LLP:~/Desktop$ ed

Why does the unread data become the next command?

John Kugelman
  • 349,597
  • 67
  • 533
  • 578
Pradeep S
  • 17
  • 2
  • That's because `stdin` is not a normal file stream but a terminal input stream. The behaviour is more like you would expect if you put it like this: `echo "test" | ./program2e3` – Cheatah Oct 26 '21 at 19:37
  • 6
    Your question should concentrate on one problem only (be more focused). For the first part of your question see [Why does printf not flush after the call unless a newline is in the format string?](https://stackoverflow.com/q/1716296/11748454). For the second part: you didn't read the entire input, so the remaining characters are read by the shell and show up in the next command line. – Piotr P. Karwasz Oct 26 '21 at 19:38
  • Thanks for your reply,I will try to be more focused hereafter.And can you suggest me any kind of resource related to ,how the terminal works ,like how it handles the input and output buffer .... – Pradeep S Oct 26 '21 at 19:45
  • Low-level control of the terminal is via [termios](https://man7.org/linux/man-pages/man3/termios.3.html) functions. [isatty(STDIN_FILENO)](https://man7.org/linux/man-pages/man3/isatty.3.html) will return 1 if standard input is a terminal. For an easier, portable, higher-level (full terminal) access, use [ncurses](https://www.man7.org/linux/man-pages/man3/ncurses.3x.html). (All editors you can run in a terminal like vi, emacs, nano use ncurses.) – Blabbo the Verbose Oct 26 '21 at 20:21
  • See also [Canonical vs non-canonical terminal input](https://stackoverflow.com/q/358342/15168). – Jonathan Leffler Oct 26 '21 at 23:01

1 Answers1

1

Because the data is still in the IO buffer in kernel rather than the STDIO buffer in your process, the unread data will be read by the next process that tries to read it (that is, the shell process). This is because the open handle was passed from the shell process to your process. Had you opened the tty device yourself that wouldn't have happened.

Joshua
  • 40,822
  • 8
  • 72
  • 132