linux 终端下敲ctrl-c时,到底发生了什么?
通过telnet登录到单板,然后按ctrl-c会发生什么情况,流程是怎么样的?
在分析之前,先介绍tty的相关知识。
我们可以认为,所有跟输入输出相关的操作,最终都由tty来接管。
举例来说,当我们敲 ls /dev时得到
[root@ dev]# ls /dev
autofs fb loop0 lp3 oldmem sda1 snapshot tty12 tty22
tty32 tty42 tty52 tty62 usbmon1
block fb0 loop1 MAKEDEV port sda2 snd tty13 tty23
tty33 tty43 tty53 tty63 usbmon2
bsg fd loop2 mapper ppp sda3 stderr tty14 tty24
tty34 tty44 tty54 tty7 usbmon3
bus full loop3 mcelog ptmx sda4 stdin tty15 tty25
tty35 tty45 tty55 tty8 usbmon4
char fuse loop4 megadev0 pts sda5 stdout tty16 tty26
tty36 tty46 tty56 tty9 usbmon5
console hpet loop5 mem random sda6 systty tty17 tty27
tty37 tty47 tty57 ttyS0 vcs
core hvc0 loop6 net rfkill sequencer tty tty18 tty28
tty38 tty48 tty58 ttyS1 vcs1
cpu input loop7 network_latency root sequencer2 tty0 tty19 tty29
tty39 tty49 tty59 ttyS2 vcsa
cpu_dma_latency kmem lp0 network_throughput rtc sg0 tty1 tty2 tty3
tty4 tty5 tty6 ttyS3 vcsa1
disk kmsg lp1 null rtc0 sg1 tty10 tty20 tty30
tty40 tty50 tty60 urandom vga_arbiter
dri log lp2 nvram sda shm tty11 tty21 tty31
tty41 tty51 tty61 usbmon0 zero
[root@ dev]#
另外还可以通过 /proc/tty/drivers得到tty相关驱动信息
[root@ dev]# cat /proc/tty/drivers
/dev/tty /dev/tty 5 0 system:/dev/tty
/dev/console /dev/console 5 1 system:console
/dev/ptmx /dev/ptmx 5 2 system
/dev/vc/0 /dev/vc/0 4 0 system:vtmaster
serial /dev/ttyS 4 64-95 serial
pty_slave /dev/pts 136 0-1048575 pty:slave
pty_master /dev/ptm 128 0-1048575 pty:master
unknown /dev/tty 4 1-63 console
[root@ dev]#
tty 控制终端,control terminal 这个是跟进程相关的,可以理解为一个指针,指向具体的tty终端设备。
进程可以通过open /dev/tty来获取当前进程使用的tty终端具体是哪个,例如是ptmx,还是pts/2,还是
tty2,或者是ttyS0
linux shell下tty命令的可以查看当前进程的控制终端。例如:
[root@ dev]# tty
/dev/pts/10
具体的实现是靠ttyname(0)
即返回当前进程的标准输入,对应的tty终端设备是哪个。
另外通过ps -ax可以查看系统所有进程的控制终端,如:
18448 ? Ss 0:06 sshd: root@pts/9
18451 pts/9 Ss+ 0:00 -bash
3424 tty2 Ss+ 0:00 /sbin/mingetty /dev/tty2
这是通过进程的/proc/pid/stat的第7个字段,当前控制终端的设备号得到的。
ptmx 伪终端主
pts 伪终端从
tty0-tty63 虚拟终端,也叫虚拟控制台终端,virtual console ternimal 通常情况下是6个,这里我们查看
的服务器有63个
tty0可以理解为指针
ttyS0-ttyS3 串口终端
刚才说到,/proc/pid/stat的第7个字段是进程控制终端的设备号,可以根据此设备号得到具体的设备名。
例如:
[root@ dev]# cat /proc/1191/stat扯远了,下面来看telnet的流程
26912 ? Ss 0:00 busybox telnetd可以看出telnetd先fork出gettty并执行login,登录成功后则再fork出实际的bash,
这个bash用的是伪终端pts/6,
以下数据的PPid字段可以证明:实际上我们可以这么理解,在直接登录shell时,没有telnetd这一层,
应该是shell进程本身被ctrl-c键盘中断打断,
然后再驱动里通过tty收到了此特殊字符,然后在接收流程里,决定是否给当前进程shell发SIG信号。