伪终端设备之我见

文章来源: http://linux.chinaunix.net/bbs/viewthread.php?tid=918470&page=1#pid6444364

Linux上许多网络服务应用,如l2tp、pptp、telnet,都用到了伪终端。有朋友在问这方面的概念,把偶知道的写下来,以供讨论。

一、终端
要理解伪终端(Pseudo Terminal),先来看看什么是“终端”(Terminal)。

终端是一种字符型设备,它有多种类型,通常使用tty来简称各种类型的终端设备。

1、串行端口终端(/dev/ttySx)
串行端口终端(Serial Port Terminal)是使用计算机串行端口连接的终端设备。计算机把每个串行端口都看作是一个字符设备。
这些串行端口所对应的设备名称是/dev/ttyS0、/dev/ttyS1等,分别对应于DOS系统下的COM1、COM2等。

[root@Kendo ~]# ls -l /dev/ttyS*
crw-rw---- 1 root uucp 4, 64 Jan  8 13:39 /dev/ttyS0
crw-rw---- 1 root uucp 4, 65 Jan  8 13:39 /dev/ttyS1
crw-rw---- 1 root uucp 4, 66 Jan  8 13:39 /dev/ttyS2
crw-rw---- 1 root uucp 4, 67 Jan  8 13:39 /dev/ttyS3

2、控制台终端(/dev/ttyn, /dev/console)
在Linux系统中,计算机显示器通常被称为控制台终端(Console)。它仿真了类型为Linux的一种终端(TERM=Linux),
与之相关联的设备文件为:tty0、tty1、tty2……。当用户从控制台上登录时,使用的是tty1。使用Alt+[F1—F6]组合键时,我们就可以切换
到tty2、tty3……上面去。tty1 –tty6等称为虚拟终端,而tty0则是当前所使用虚拟终端的一个别名,系统所产生的信息会发送到该终端上。
因此不管当前正在使用哪个虚拟终端,系统信息都会发送到控制台终端上。用户可以登录到不同的虚拟终端上去,因而可以让系统同时有几
个不同的会话期存在。只有系统或超级用户root可以向/dev/tty0进行写操作。

作为一个测试例子,在控制台终端下,运行命令:

#echo "write to ttyS0" > /dev/ttyS0

在串行端口终端中可以看到输出:

# write to ttyS0

3、控制终端(/dev/tty)
控制终端并不面对设备,而是面对进程,关于这个概念,《Unix环境高级编程》第9章有详细论述。

二、从终端登录简述

Linux系统引导的时候,会运行init进程,它会执行/etc/inittab(这跟具体的init类型有关,我使用了busybox的init,但其本质是一样的):

[root@SkyNet ~]# cat /etc/inittab
::sysinit:/etc/init.d/rcS
::respawn:/sbin/getty 9600 ttyS0

它会调用getty在指定波特率上打开ttyS0,即,串行端口终端。打开成功后,stdout,stdin,stderr都被设置到该备上,然后getty输出:"login:"之类的提示符,等待用户输入。

当用户键入用户名后,getty就执行login程序,类似于:execle("login")。login可以调用getpass()以显示 Password:并读入用户口令。并且调用getpwnam进行口令验证。如果成功,调用类似execle("shell")。这样,登录用户就拥有了 一个shell了。

三、伪终端
上述登录过程,对于网络用户来说,却不能完全实用。很显然,网络用户并不需要一个串口,也不需要一个显示器,他需要的是在他的本地显示设备上,
运行Linux的shell。以telnetd为例,它至少应该是这样子的:

图一:telnet登录假想图

这里,这个“某个终设备”,自然不可能是一个实际的物理终端设备,因为压根没有这样的设备。这样,伪终端的概念就被引入进来了。伪终端设备是一种特殊的终 端驱动设备, 它并不驱动某个物理设备,而是用来将终端的输出定向到应用程序中进行处理。伪终端设备之所以存在是为了提供在程序控制下的一种模拟串行终端行为的方法。

伪终端与前面说的终端在表现形式上,最大的不同,就是它总是成对出现,而不是单一的一个。它分为“伪终端主设备(/dev/ptyMN)”和“伪终端从设备”。(/dev/ttyMN)。其中,M与N的命名方式如下:

M: p q r s t u v w x y z a b c d e 共16 个
N: 0 1 2 3 4 5 6 7 8 9 a b c d e f 共16 个

这样,默认支持最大是256个。

任何写入到伪终端主设备的输入,都会作为伪终端从设备的输入,反之亦然。类似于管道,如下图:

一个典型的伪终端进程结构如下图:

这张图的关键在于:如果把伪终端从设备想像为传统的终端设备,把主设备看成进程读写数据的一个“接口”,那么它的工作原理,就跟传统终端一样了。

上述只是一个本地进程,把网络引入进来,对应到telnetd上面来,应该是下面这个样子:


同样的登录方式,就变成了这样:
1、如果某人在网上使用telnet程序连接到本地服务器,则telnetd程序就可能会开始连接到设备ptyp2(m2)上(一个伪终端主设备上)。
2、telnetd产生一个子进程,进行getty程序,其打开一个对应的从设备对应的ttyp2(s2),并设置stdin/stdout/stderr;
3、telnetd通过内核tcp/ip协议栈从远端获取了一个字符时,该字符就会通过m2、s2传递给getty程序,而getty程序就会通过s2、m2和telnetd程序往网络上返回”login:”字符串信息;
4、这样,登录程序与telnetd程序就通过“伪终端”进行通信;

四、伪终端的数量
对于Linux下的应用而言,知道伪终端的数量是一个关键的东东,或者它直接决定了最大支持用户数,例如PPTP VPN的应用。(没有多余的可以供打开的
伪终端设备了)。
对于2.6.X而言,在

Device Drivers  --->
Character devices  --->
[*] Legacy (BSD) PTY support
        (256) Maximum number of legacy PTY in use

可以设定。应该将它调整到足够地大,以供支持应用。同时,/dev目录下,应该有相应的设备文件:

#ls -l /dev/ptyp*
crw-r--r--    1 root     root       2,   0 Dec 18 05:36 /dev/ptyp0
crw-r--r--    1 root     root       2,   1 Dec 18 05:36 /dev/ptyp1
crw-r--r--    1 root     root       2,   2 Dec 18 05:36 /dev/ptyp2
crw-r--r--    1 root     root       2,   3 Dec 18 05:36 /dev/ptyp3



#ls -l /dev/ttyp*
crw-------    1 root     root       3,   0 Dec 18 05:36 /dev/ttyp0
crw-------    1 root     root       3,   1 Dec 18 05:36 /dev/ttyp1
crw-r--r--    1 root     root       3,   2 Dec 18 05:36 /dev/ttyp2
crw-------    1 root     root       3,   3 Dec 18 05:36 /dev/ttyp3

这样命令方式,并且要指定数量的方式实在是让人郁闷。因为它有一个数量上限的问题,最大256。

为了解决这个问题,Linux引入了一种新的命名方式:UNIX98_PTYS。关于这个东东,内核是这样解释的:

        Linux has traditionally used the BSD-like names /dev/ptyxx for
masters and /dev/ttyxx for slaves of pseudo terminals. This scheme
has a number of problems. The GNU C library glibc 2.1 and later,
however, supports the Unix98 naming standard: in order to acquire a
pseudo terminal, a process opens /dev/ptmx; the number of the pseudo
terminal is then made available to the process and the pseudo
terminal slave can be accessed as /dev/pts/<number>. What was
traditionally /dev/ttyp2 will then be /dev/pts/2, for example.

        All modern Linux systems use the Unix98 ptys.  Say Y unless
you're on an embedded system and want to conserve memory.

这样,可以通过访问/dev/ptmx设备文件的形式,来访问伪终端设备了,例如我的PPTP服务器,当有五个用户拨入后:

# ls -l /dev/pts/            
crw-------    1 root     root     136,   0 Jan  8 12:18 0
crw-------    1 root     root     136,   1 Jan  8 08:08 1
crw-------    1 root     root     136,   2 Jan  8 14:10 2
crw-------    1 root     root     136,   3 Jan  8 14:27 3
crw-------    1 root     root     136,   4 Jan  8 08:29 4
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
要在Ubuntu 20.04中配置输出设备为虚拟输出,您可以按照以下步骤进行操作: 1. 打开终端,输入以下命令以编辑`alsa-base.conf`文件: ``` sudo gedit /etc/modprobe.d/alsa-base.conf ``` 引用 2. 在打开的文件中,添加以下内容: ``` options snd-hda-intel dmic_detect=0 ``` 您可以直接输入以下命令并回车: ``` echo options snd-hda-intel dmic_detect=0 | sudo tee -a /etc/modprobe.d/alsa-base.conf ``` 引用 3. 接下来,编辑`blacklist.conf`文件,输入以下命令: ``` sudo gedit /etc/modprobe.d/blacklist.conf ``` 引用 4. 在打开的文件中,添加以下内容: ``` blacklist snd_soc_skl ``` 您也可以直接输入以下命令并回车: ``` echo blacklist snd_soc_skl | sudo tee -a /etc/modprobe.d/blacklist.conf ``` 引用 5. 保存文件并关闭编辑器。 6. 最后,重新启动系统以使更改生效。您可以使用以下命令重启系统: ``` sudo reboot ``` 请注意,重新启动可能需要一些时间。 完成上述步骤后,您的Ubuntu 20.04系统的输出设备将被配置为虚拟输出。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [Ubuntun20.04声音无法输出(显示输出)的问题](https://blog.csdn.net/qq_45805535/article/details/108416417)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *3* [解决ubuntu20.04系统不发出声音、显示输出(dummy output)的问题](https://blog.csdn.net/DBaiYun/article/details/125765033)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值