LinuxLinux学习之路

APUE读书笔记-19伪终端(2)

2020-09-28  本文已影响0人  QuietHeart

2、概述

伪终端的意思是,这个终端对于应用程序来说表现像是一个终端,但是实际上它并不是一个真正的终端。下面的图就展示了一个典型的进程使用伪终端的组织结构。

典型的伪终端

进程使用伪终端的典型结构

         +----------+         +----------+
         |    user  |  fork   |   user   |
         |  process |-------->|  process |
         +-----^----+  exec   +-----^----+
               |                    |stdin,stdout,stderr
+- - - - - - - - - - - - - - - - - - - - - - - - -+
|              |                    |             |
     +---------v-------+   +--------v-------+
|    | read and write  |   | read and write |     |
     |    functions    |   |    functions   |
|    +-----|-----^-----+   +----|------^----+     |
           |     |              |      |
|          |     |         +----v------|----+     |
           |     |         |    terminal    |       Kernel
|          |     |         | line dscipline |     |
           |     |         +----|------^----+
|          |     |              |      |          |
     +-----v-----|-----+   +----v------|----+
|    | pseudo-terminal |   | pseudo-terminal|     |
     |     master      |   |     slave      |
|    +-----|-----^-----+   +----|------^----+     |
           |     |              v      |
|          |     +<-------------+      |          |
           v                           |
|          +-------------------------->+          |
+- - - - - - - - - - - - - - - - - - - - - - - - -+
  1. 一般来说,进程打开伪终端主控端(后面用pseudo-terminal master表示),然后调用fork。子进程建立新的会话,打开相应的伪终端从控端(后面用pseudo-terminal slave表示),复制文件描述符号到标准输入、标准输出、标准错误输出,然后调用exec。pseudo-terminal变成子进程的控制终端。
  2. 对于slave端的用户进程来说,它的标准输入,标准输出,以及标准错误输出是一个终端设备。进程可以对这些文件描述符号调用所有前面描述的终端I/O相关的函数。但是,因为在slave下面没有真正的终端设备,所以不会起作用的那些函数(改变波特率,发送break字符,设置oddparity等),会被忽略。
  3. 任何写入到master端的内容都会被视作slave端的输入,反之亦然。实际上,所有到达slave端的输入来自pseudo-terminal master上面的用户进程。这个行为看起来就像是一个双向的管道。但是通过slave上面的终端行规范模块,我们可以有除了管道之外更多的能力。

上面的图中的伪终端表现是FreeBSD,Mac OS X, 或者 Linux系统上面的大致情况。后面,我们将要展示如何打开这些设备。

Solaris的伪终端

在Solaris下,伪终端通过使用STREAMS子系统构建。下面的图形列出了Solaris下面的伪终端STREAMS模块的组织结构。两个用虚线框起来的STREAMS模块(ttcompat和pckt)是可选的。pckt和ptem模块用来提供伪终端的语义规范。另外两个模块(ldterm和ttcompat)提供行处理规范。

Solaris下面伪终端的结构

         +----------+         +----------+
         |    user  |  fork   |   user   |
         |  process |-------->|  process |
         +-----^----+  exec   +-----^----+
               |                    |stdin,stdout,stderr
+- - - - - - - - - - - - - - - - - - - - - - - - -+
|              |                    |             |
     +---------v-------+   +--------v-------+
|    |  stream head    |   |   stream head  |     |
     +-----|-----^-----+   +----|------^----+
|          |     |              |      |          |
           |     |         +- - v- - - |- - +
|          |     |         .    ttcompat    .     |
           |     |         . STREAMS module .
|          |     |         + - -| - - -^ - -+     |
           |     |              |      |
|          |     |         +----v------|----+     |
           |     |         |     ldterm     |
|          |     |         | STREAMS module |     | kernel
           |     |         +----|------^----+
|          |     |              |      |          |
     +- - -v- - -|- - -+   +----v------|----+
|    .      pckt       .   |      ptem      |     |
     .  STREAMS module .   | STREAMS module |
|    +- - -|- - -^- - -+   +----|------^----+     |
|          |     |              |      |          |
     +-----v-----|-----+   +----v------|----+
|    | pseudo-terminal |   | pseudo-terminal|     |
     |     master      |   |     slave      |
|    +-----|-----^-----+   +----|------^----+     |
           |     |              v      |
|          |     +<-------------+      |          |
           v                           |
|          +-------------------------->+          |
+- - - - - - - - - - - - - - - - - - - - - - - - -+

需要注意的是slave上面的三个STREAMS模块和以前"高级输入输出"中的一个名为"列出stream上的模块名称"的用于网络登陆的代码中的输出是一样。后面我们将会展示如何构建这个结构的STREAMS模块。

现在开始,我们将要通过去掉"read and write functions"来简化前面的"进程使用伪终端的典型结构"图形,或者通过去掉"stream head"简化前面的"Solaris下面伪终端的结构"图形。我们将会使用PTY表示伪终端的简写,把前面"Solaris下面伪终端的结构"的slave PTY之上所有的STREAMS模块放到"terminal line discipline"盒子中。

上一篇下一篇

猜你喜欢

热点阅读