简体   繁体   English

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

[英]How does input echoing work in a Linux terminal?

Consider the following code: 请考虑以下代码:

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

This programs sleeps for a second, then disables echoing of input characters, then reads an input character. 此程序休眠一秒钟,然后禁用输入字符的回显,然后读取输入字符。

If I type an input character after echoing has been disabled, the character is not echoed. 如果在禁用回显后键入输入字符,则不回显该字符。 So far, so good. 到现在为止还挺好。

If I type an input character before echoing is disabled, the character is echoed. 如果在禁用回显之前键入输入字符,则回显该字符。 But the program is sleeping at this time. 但是这个节目正在睡觉。 My question is: if the program is sleeping, what is doing the echoing ? 我的问题是: 如果程序正在睡眠,那么回音是什么

My motivation for asking this is that a similar program on Windows (obviously the specific mechanism of disabling echoing being different) behaves differently: even if I type an input character while the program is sleeping, no echoing happens, and then when the program wakes up from the sleep it disables echoing before running code that would do the echoing ( getchar() ), and therefore still no echoing happens. 我要求这样做的动机是Windows上的类似程序(显然禁用回显的具体机制不同)表现不同:即使我在程序休眠时键入输入字符,也不会发生回显,然后当程序唤醒时从睡眠状态开始,它会在运行可以进行回显的代码( getchar() )之前禁用回显,因此仍然不会发生回显。

My question is: if the program is sleeping, what is doing the echoing? 我的问题是:如果程序正在睡眠,那么回音是什么?

The kernel's tty layer. 内核的tty层。

Input and output that passes through a tty — whether it's a serial port, a virtual console, or a pty — is processed by the kernel according to the current configuration of that tty. 通过tty的输入和输出 - 无论是串行端口,虚拟控制台还是pty - 由内核根据该tty的当前配置进行处理。 This processing is surprisingly complex, and can include all of the following features: 此处理非常复杂,可以包含以下所有功能:

  • Queueing of input and output and handling flow control 输入和输出的排队以及处理流量控制
  • Baud rate and parity handling (for serial lines) 波特率和奇偶校验处理(用于串行线路)
  • Keeping track of the size of the terminal, in rows and columns 按行和列跟踪终端的大小
  • Line buffering and editing 线缓冲和编辑
  • Echoing input to output 将输入回应到输出
  • Character conversions: 角色转换:
    • Conversion of output newlines to CR + NL sequences 将输出换行符转换为CR + NL序列
    • Conversion of input backspaces to DEL characters 将输入退格键转换为DEL字符
    • Conversion of tabs to spaces (off by default) 将标签转换为空格(默认情况下关闭)
    • Conversion of backspaced characters to alternate sequences, eg abc^H^H^H to abc\\cba/ (off by default, was used for hardcopy terminals that can't erase characters) 将退格符号转换为备用序列,例如abc^H^H^Habc\\cba/ (默认情况下关闭,用于无法擦除字符的硬拷贝终端)
  • Interpreting input control sequences of various types: 解释各种类型的输入控制序列:
    • Some send signals to the foreground process, like ^C and ^Z . 一些发送信号到前台进程,如^ C^ Z.
    • Some trigger basic line editing in the kernel, such as ^H for backspace, ^W for kill-word, and ^U for kill-line. 有些触发内核中的基本行编辑,例如^ H表示退格, ^ W表示kill-word, ^ U表示kill-line。
    • Some interact with flow control, like ^S and ^Q . 有些与流控制相互作用,如^ S^ Q.

In short, there's a lot of work being done by the kernel's tty layer! 简而言之,内核的tty层正在做很多工作! It's doing much more than just passing input to output. 它不仅仅是将输入传递给输出。

Windows does not have a tty layer in the same sense as UNIX systems. Windows没有与UNIX系统相同的tty层。 It does have a console, but it works very differently — my understanding is that it's largely designed to emulate the text mode of the PC BIOS, not a terminal. 它确实有一个控制台,但它的工作方式非常不同 - 我的理解是它主要用于模拟PC BIOS的文本模式,而不是终端。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM