read()在stdin上返回EOF而不是等待输入

时间:2011-10-12 05:57:56

标签: c stdin termios

有谁知道为什么运行以下代码可能导致该fd(stdin)上的所有未来read()调用立即返回0而不是阻塞输入?

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

删除tcsetattr行使read()按预期工作。

也尝试过:

fcntl(inFd, F_SETFL, 0);

没有运气。

请注意,我目前有2个不同的终端。在其中一个中运行应用程序会导致读取立即返回。在另一个中运行它会导致读取阻止输入。它可能是什么?

提前致谢: - )

Repro来源:

#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;
}

2 个答案:

答案 0 :(得分:0)

我认为你的问题是掩盖ICANON,ICANON反过来关闭规范模式(启用非规范模式)。根据termios(3)的联机帮助页:

“在非规范模式下,输入立即可用(用户不必键入行分隔符),并禁用行编辑。”

为避免使这篇文章变得混乱,请参阅手册页,因为它详细解释了这种行为。当read没有返回时(如在异步模式下),会发生以下行为。

Gergely来自toptal Engineering

答案 1 :(得分:0)

  

请记住,tty驱动程序维护一个字节输入队列   已经从串行线读取而不是传递给用户,所以没有   每个read()调用都等待实际的I / O - 读取可能很好   直接从输入队列中得到满足。

参考here