开发者

read() on stdin returning EOF instead of waiting for input

Does anyone know why running the following code may cause all future read() calls on that fd (which is stdin) to immediately return 0 instead of blocking for 开发者_StackOverflow社区input?

termios newTerminalSettings;
tcgetattr(inFd, &newTerminalSettings);
newTerminalSettings.c_lflag &= ~ICANON;
tcsetattr(inFd, TCSANOW, &newTerminalSettings);

Removing the tcsetattr line makes read() work as expected.

Also tried:

fcntl(inFd, F_SETFL, 0);

with no luck.

Note that I currently have 2 different terminals. Running the app in one of them causes read to return instantly. Running it in the other causes read to block for input. What could it be?

Thanks in advance :-)

Repro source:

#include <iostream>
#include <termios.h>

using namespace std;

int main(void) {
    termios newTerminalSettings;
    tcgetattr(0, &newTerminalSettings);
    newTerminalSettings.c_lflag &= ~ICANON;
    tcsetattr(0, TCSANOW, &newTerminalSettings);

    char readBuf[5000];
    cout << "read returned: " << read(0, readBuf, sizeof(readBuf));

    return 0;
}


I think your problem is masking out ICANON, which in turn turns off canonical mode (enables noncanonical mode). According to the manpage of termios(3):

"In noncanonical mode input is available immediately (without the user having to type a line-delimiter character), and line editing is disabled."

To avoid cluttering this post, please see the man page, as it explains this behavior in detail. The following behavior happens when read has nothing to return (as in asynchronous mode).

Gergely from toptal Engineering


Keep in mind that the tty driver maintains an input queue of bytes already read from the serial line and not passed to the user, so not every read() call waits for actual I/O - the read may very well be satisfied directly from the input queue.

Refer here

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜