If I run
strace -e trace=ioctl -v ssh some_remote_host
I see a line like this:
ioctl(0, SNDCTL_TMR_STOP or TCSETSW, {c_iflags=0x6006, c_oflags=0x4, c_cflags=0x
4bf, c_lflags=0xa00, c_line=0, c_cc[VMIN]=1, c_cc[VTIME]=0, c_cc="\x03\x1c\x7f\x
15\x04\x00\x01\xff\x11\x13\x1a\xff\x12\x0f\x17\x16\xff\x00\x00"}) = 0
Which makes sense: ssh has to change a lot of terminal settings, for example:
- it turns off
ISIGbecause ^C and ^Z should interrupt and suspend the process on the remote host, not thesshprocess running locally; - it turns off
ICANONbecause it wants to receive keyboard input unbuffered rather than line buffered; - it turns off
ECHObecause whether echoing occurs should depend on the attributes set on the remote host's pseudo-terminal, instead of occurring automatically on the local terminal
If you now exit the ssh session, the original terminal attributes are restored by a second ioctl call:
ioctl(0, SNDCTL_TMR_STOP or TCSETSW, {c_iflags=0x6d02, c_oflags=0x5, c_cflags=0x
4bf, c_lflags=0x8a3b, c_line=0, c_cc="\x03\x1c\x7f\x15\x04\x00\x01\xff\x11\x13\x
1a\xff\x12\x0f\x17\x16\xff\x00\x00"}) = 0
But what I find strange is that even if ssh is killed with SIGKILL before it has the chance to make the second ioctl call, you get the original terminal attributes back. Otherwise you would notice that something is very wrong (for example commands typed into the shell would not be echoed). How does ssh manage to ensure that the original terminal attributes are restored even if it's not around to call ioctl again?