- 论坛徽章:
- 2
|
回复 1# allen303allen
这个其实用远程登录的例子最好理解。tty最复杂的逻辑在于对原始输入的解释,如读到一行才返回给用户,处理特殊字符(intr,quit,et.),展开tab,大小写转换,转义字符等。而这些都是硬件无关的,与硬件相关的是硬件驱动注册的中断处理函数填充输入队列,以及硬件驱动提供的输出函数。只要提供这两点,就有可以作为tty设备(呈现tty设备属性)。换句话说,只要具有输入输出属性的设备都可以作为tty设备。比如将键盘与显示器(被拆分为两部分的tty设备),串口等。
网络显然也具有这种属性。远程登录时服务器端有进程监听端口,当进程从网络中获得输入时可作为tty设备的输入(就好像从键盘上获得输入一样),而内核想从该tty设备输出时则经由进程从网络输入(就像从显示器输出一样)。但问题是,当进程从网络得到数据时,数据已经到用户态了。而内核想输出时,数据也只是在内核态流动。所以监听进程打开伪终端,得到一个master侧的tty的slave侧的tty,然后fork另外一个进程,将其标准输入输出都设为slave端的tty,子进程exec另一个程序,比如bash。这样bash从slave tty设备读,写到slave tty;监听程序从master tty读,写到master tty。当监听程序从网络上读到数据了,就将数据写到master tty,而master tty的输出连在slave tty的输入上,这样数据就流到了slave tty的输入列队上。正常情况是由硬件中断函数提供输入队列上的数据,而这里由监听进程从用户态通过master tty的输出端将数据传到slave tty的输入队列上。而写向slave tty的数据流到了master tty的输入队列上,监听进程可以从master的输入端读到数据。正常情况下向tty写的数据会在内核态直接由硬件驱动程序输出(最终在硬件上传输),这里写向slave tty的数据却流到master tty的输入队列并且被监听进程读到用户态,然后向网络中发送。最终的效果是,bash读写的slave tty,数据从网络中来,数据到网络中去,中间由tty逻辑使其具有刚才所述的一系列属性。普通的tty数据流入流出都由内核态驱动处理,而slave tty数据的流入流出最终却是有用户态处理,然而结果与普通tty无异。 |
|