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

发布于 2024-12-09 09:27:39 字数 922 浏览 0 评论 0原文

有谁知道为什么运行以下代码可能导致对该 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 立即返回。在其他中运行它会导致读取阻塞以获取输入。可能是什么?

预先感谢:-)

复制来源:

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

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

不寐倦长更 2024-12-16 09:27:39

我认为你的问题是屏蔽了 ICANON,这又会关闭规范模式(启用非规范模式)。根据 termios(3) 的联机帮助页:

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

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

来自toptal Engineering的Gergely

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

长安忆 2024-12-16 09:27:39

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

请参阅此处

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文