'How to read from STDIN_FILENO with blocking I/O

How can I read from STDIN_FILENO with blocking, I/O, i.e. I won't get -1 if there isn't any data. Seems that I have to clone the handle somehow. But I don't know why.



Solution 1:[1]

If you read from stdin with

read(STDIN_FILENO, buf, COUNT);

it will block until COUNT bytes are read.

Solution 2:[2]

Here's the solution that also makes the console temporarily non-canonical:

if( isatty( STDIN_FILENO ) )
{
    termios tiosSave, tiosNew;
    tcgetattr( STDIN_FILENO, &tiosSave );
    tiosNew = tiosSave;
    tiosNew.c_lflag &= ~(tcflag_t)(ICANON | ECHO);
    tiosNew.c_cc[VMIN] = 1;
    tiosNew.c_cc[VTIME] = 0;
    tcsetattr( STDIN_FILENO, TCSAFLUSH, &tiosNew );
    char ch;
    (void)read( STDIN_FILENO, &ch, 1 );
    tcsetattr( STDIN_FILENO, TCSAFLUSH, &tiosSave );
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Diego Torres Milano
Solution 2 Bonita Montero