【问题标题】:read() on stdin returning EOF instead of waiting for input标准输入上的 read() 返回 EOF 而不是等待输入
【发布时间】:2011-12-05 20:36:56
【问题描述】:

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

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

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

也试过了:

fcntl(inFd, F_SETFL, 0);

没有运气。

请注意,我目前有 2 个不同的终端。在其中一个中运行应用程序会导致 read 立即返回。在其他情况下运行它会导致 read 阻塞输入。会是什么?

提前致谢:-)

复制来源:

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

【问题讨论】:

    标签: c stdin termios


    【解决方案1】:

    我认为您的问题是屏蔽了 ICANON,这反过来会关闭规范模式(启用非规范模式)。根据 termios(3) 的手册页:

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

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

    来自toptal Engineering的Gergely

    【讨论】:

      【解决方案2】:

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

      参考here

      【讨论】:

        猜你喜欢
        • 2023-02-14
        • 2012-08-21
        • 1970-01-01
        • 1970-01-01
        • 2017-07-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多