【问题标题】:How does a tty in linux get input and pass in into a program. And how to fetch it?linux中的tty如何获取输入并传入程序。以及如何获取它?
【发布时间】:2021-01-17 20:35:20
【问题描述】:

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

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

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

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

【问题讨论】:

  • This question 可能会为您提供一些有用的信息。请注意,当您使用 tty 时,程序的标准输入是由 tty 写入并由程序读取的虚拟文件。如果 tty 没有将某些内容刷新到该虚拟文件,则您的代码无法读取它。
  • 所以在这种情况下,我的程序在读取(处理信号)期间被中断,我想获取该数据(打印它)。我应该将“已接收但尚未读取”的数据刷新到文件中并开始读取它。对吗?

标签: c linux io tty ioctl


【解决方案1】:

简答:

termios.h,一个 POSIX 标准的头文件,允许您将 tty 置于 raw 模式,而它通常处于 cooked 模式

建议阅读它的文档/手册页。

通过termios.h 处理逐步设置原始模式的网页链接here

说明:

默认情况下,终端的 I/O 是line-buffered,即保证一旦一行终止,输入就会被刷新/发送到您的程序。

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

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

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

【讨论】:

  • termios.h。没有n
  • 感谢您的回答。我已将 tty 设置为原始模式,但现在我必须为我想要完成的任务设置一个类似 readline 的替代方案。
  • @abakfja 啊,删除整个抽象结构的经典问题只是为了获得删除 1% 的好处。欢迎来到低级编程。如果您觉得我应得的,请点赞我的答案:)
  • @rici 我的生活是个谎言。
  • @abakfja:也许你最好直接使用 readline 库,而不是尝试重新实现它(这将是一项艰巨的任务)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多