输入回显如何在Linux终端中工作?

时间:2014-04-26 22:09:21

标签: c linux input terminal

请考虑以下代码:

#include <stdio.h>
#include <termios.h>
#include <unistd.h>

void disable_echoing()
{
    termios t;
    tcgetattr(STDIN_FILENO, &t);
    t.c_lflag &= ~ECHO;
    tcsetattr(STDIN_FILENO, TCSANOW, &t);
}

int main()
{
    sleep(1);
    printf("disabling echoing\n");
    disable_echoing();
    getchar();
}

此程序休眠一秒钟,然后禁用输入字符的回显,然后读取输入字符。

如果在禁用回显后键入输入字符,则不回显该字符。到目前为止,非常好。

如果在禁用回显之前键入输入字符,则会回显该字符。但是这个节目正在睡觉。我的问题是:如果程序正在休眠,那么回音是什么?

我要求这样做的动机是,Windows上的类似程序(显然禁用回显的具体机制不同)表现不同:即使我在程序休眠时键入输入字符,也不会发生回显,然后当程序从睡眠状态唤醒它会在运行能够进行回显的代码(getchar())之前禁用回显,因此仍然不会发生回显。

1 个答案:

答案 0 :(得分:4)

  

我的问题是:如果程序正在休眠,那么回音是什么?

The kernel's tty layer.

通过tty的输入和输出 - 无论是串行端口,虚拟控制台还是pty - 由内核根据该tty的当前配置进行处理。此处理非常复杂,可以包含以下所有功能:

  • 输入和输出的排队以及处理流量控制
  • 波特率和奇偶校验处理(用于串行线路)
  • 以行和列的形式跟踪终端的大小
  • 线路缓冲和编辑
  • 将输入回显到输出
  • 字符转换:
    • 将输出换行符转换为CR + NL序列
    • 将输入退格键转换为DEL字符
    • 将标签转换为空格(默认情况下已关闭)
    • 将退格符号转换为备用序列,例如abc^H^H^Habc\cba/(默认关闭,用于无法删除字符的硬拷贝终端)
  • 解释各种类型的输入控制序列:
    • 有些人会向前台进程发送信号,例如 ^ C ^ Z
    • 有些触发内核中的基本行编辑,例如 ^ H 表示退格, ^ W 表示kill-word, ^ U for kill-line。
    • 有些与流量控制互动,例如 ^ S ^ Q

简而言之,内核的tty层正在完成很多工作!它不仅仅是将输入传递给输出。

Windows没有与UNIX系统相同的tty层。它确实有一个控制台,但它的工作方式却截然不同 - 我的理解是它主要用于模拟PC BIOS的文本模式,而不是终端。