linux 中的 tty 如何获取输入并传入程序。以及如何获取它?

How does a tty in linux get input and pass in into a program. And how to fetch it?

假设我有一个具有以下循环的 C 程序。

while ((c = getchar()) != EOF) {
    ...
}

这个循环看起来就像是在 tty 上键入字符时一个字符一个字符地读取。但是一旦输入字符,我就不应该更改字符,显然,这不会发生。
这一定意味着 tty 必须保留一些缓冲区以保留它已收到但尚未推送到标准输入的值。一旦进入标准输入,字符就会被一个一个地读取。

这是正确的吗?如果是这样,我怎样才能获得这个缓冲区中的字符,而不必去标准输入?我尝试将 ioctl 与 FIONREAD 一起使用,但它似乎不起作用(缓冲区的大小始终为零,即使终端中有字符),并且由于此数据不在标准输入中,这意味着从标准输入读取的方法不会工作(这些是作为类似问题的答案给出的)

简答:

termios.h,一个 POSIX-standard 头文件,允许你让 tty 进入 raw 模式 而它通常处于 cooked模式 .

建议阅读 documentation/man 页。

已链接 step-by-steptermios.h 设置原始模式的网页 here

解释:

默认情况下,终端的I/O是line-buffered,即输入一次保证是flushed/sent到你的程序行已终止。

在输出中,这是通过 \nfflush(stdout); ,而在输入中,这是通过用户按下 [ENTER] 键。

让终端进入 raw 模式允许它在按下一个键时立即将输入信号发送到您的程序,以及许多其他回显等默认功能被禁用。

对于任何稍微复杂的 CLI 程序,尤其是像 vim、htop 等这样的程序,这都是很常见的。