Pergunta

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.

Foi útil?

Solução

My question is: if the program is sleeping, what is doing the echoing?

The kernel's tty layer.

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. 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
    • Conversion of input backspaces to DEL characters
    • Conversion of tabs to spaces (off by default)
    • Conversion of backspaced characters to alternate sequences, e.g. abc^H^H^H to abc\cba/ (off by default, was used for hardcopy terminals that can't erase characters)
  • Interpreting input control sequences of various types:
    • Some send signals to the foreground process, like ^C and ^Z.
    • Some trigger basic line editing in the kernel, such as ^H for backspace, ^W for kill-word, and ^U for kill-line.
    • Some interact with flow control, like ^S and ^Q.

In short, there's a lot of work being done by the kernel's tty layer! 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. 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.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top