《Unix环境高级编程》笔记 第九章-进程关系

本文详细介绍了Unix系统中终端登录、网络登录的过程,以及进程、进程组、会话、控制终端之间的关系。通过终端登录时,init进程启动getty程序,getty执行login验证用户,然后启动shell。网络登录涉及inetd进程处理网络请求,调用telnetd服务程序,通过伪终端实现。文章还讨论了会话、进程组的概念,以及如何为会话分配控制终端。同时解释了控制终端与进程组、会话之间的逻辑关系及其作用。
摘要由CSDN通过智能技术生成

1. 终端登录

本节介绍经由终端登陆至UNIX系统所执行的各个程序。

1.1 终端是什么 Terminal

https://blog.csdn.net/yazhouren/article/details/78793367

终端就是处理计算机主机输入输出的一套设备,它用来显示主机运算的输出,并且接受主机要求的输入,典型的终端包括显示器键盘套件,打印机打字机套件等

1.2 终端类型

终端文件(/dev/…)都是字符设备文件 (char)

  • 本地终端
    用VGA连接主机和显示器,用PS/2或者USB连接主机和键盘,这样的一个显示器/键盘组合就是一个本地终端。
  • 用串口连接的远程终端
    通过串口线把主机接到另外一个有显示器和键盘的主机,通过运行一个终端模拟程序,比如***“Windows超级终端”***来将这台主机的显示器和键盘借给串口对端的主机。
  • 用TCP/IP承载的远程终端
    类似Telnet,SSH这般。

可见上述的三类中,前两类都是在本地就直接关联了物理设备的,比如VGA口啊,PS/2口啊,串口啊之类的,这种终端叫做物理终端而第三类在本地则没有关联任何物理设备,注意,不要把物理网卡当成终端关联的物理设备,它只是隧道关联的物理设备,这里的物理网卡完全可以换成卡车,它们与终端并不直接相关,所以这类不直接关联物理设备的终端叫做伪终端

  • 串行端口终端(Serial Port Terminal)

    在linux中的表现形式/dev/ttyS#

    是使用计算机串行端口连接的终端设备。计算机把每个串行端口都看作是一个字符设备。有段时间这些串行端口设备通常被称为终端设备,因为那时它的最大用途就是用来连接终端。这些串行端口所对应的设备名称是/dev/tts/0(或/dev/ttyS0), /dev/tts/1(或/dev/ttyS1)等,设备号分别是(4,0), (4,1)等,分别对应于DOS系统下的COM1、COM2等。若要向一个端口发送数据,可以在命令行上把标准输出重定向到这些特殊文件名上即可。例如,在命令行提示符下键入:echo test > /dev/ttyS1会把单词”test”发送到连接在ttyS1(COM2)端口的设备上。可接串口来实验

  • 伪终端

    https://www.cnblogs.com/zzdyyy/p/7538077.html

    在linux中的表现形式/dev/pts/#

    虚拟终端和串行终端的数目是有限的,然而,网络终端和图形终端窗口的数目确是不受限制的,这是通过伪终端实现的。即为远程连接的终端或图形界面下打开的终端接口

    伪终端是伪终端master和伪终端slave(终端设备文件)这一对字符设备/dev/ptmx是用于创建一对master、slave的文件。当一个进程打开它时,获得了一个master的文件描述符(file descriptor),同时在/dev/pts下创建了一个slave设备文件。

    master端是更接近用户显示器、键盘的一端,slave端是在虚拟终端上运行的CLI(Command Line Interface,命令行接口)程序。Linux的伪终端驱动程序,会把“master端(如键盘)写入的数据”转发给slave端供程序输入,把“程序写入slave端的数据”转发给master端供(显示器驱动等)读取。

在这里插入图片描述

我们打开的“终端”桌面程序,其实是一种终端模拟器(即为使用Ctrl+Alt+T打开的那个)。当终端模拟器运行时,它通过/dev/ptmx打开master端,创建了一个伪终端对,并让shell运行在slave端。当用户在终端模拟器中按下键盘按键时,它产生字节流并写入master中,shell便可从slave中读取输入;shell和它的子程序,将输出内容写入slave中,由终端模拟器负责将字符打印到窗口中。

利用伪终端完成远程登录:

每次用户通过客户端连接服务端的时候,服务端创建一个伪终端master、slave字符设备对,在slave端运行login程序,将master端的输入输出通过网络传送至客户端。至于客户端,则将从网络收到的信息直接关联到键盘/显示器上。我们将这个过程描述为下图:

在这里插入图片描述

  • 虚拟终端

    对应的文件是/dev/tty#

    虚拟终端是机器正常启动后自动启动的控制台。Linux除了有图形化界面外,还有纯命令行界面,并且默认情况下,你可以同时操作最多6个纯命令行界面,这些纯命令行界面被称作Virtual Terminal(虚拟终端)。

    当你登录Linux服务器的时候,默认只能使用虚拟终端。此外,即便是普通的桌面环境,当你需要重新配置图形界面,或者图形界面因为内部异常等原因崩溃了的时候,你还可以切换到虚拟终端继续执行操作。可以用Ctrl+Alt+F1到Ctrl+Alt+F6来切换(缺省只开6个虚拟终端)
    其设备控制文件分别为/dev/tty1、/dev/tty2、/dev/tty3、/dev/tty4、/dev/tty5和/dev/tty6
    还有/dev/tty0是对应当前的虚拟终端

  • 控制台:注意区分控制台和终端的区别

    https://blog.csdn.net/lwy19880425/article/details/52791247

    对应的文件是/dev/console

    **在主机的系统启动完成之前,终端是不能连接到主机上的。**为了能记录出主机开机过程的日志,也便于在主机出故障无法启动操作系统时进行检修维护,就多了一个叫做控制台的设备。**一台主机有且只能有一个控制台。**文件主机的重要日志,比如开机关机的日志和记录,重要应用程序的日志,都会输出到控制台来。

    console 相当于电视机机体上的控制面版,一般只有一个;terminal 相当于遥控器,可以有很多个

    计算机启动的时候,所有的信息都会显示到控制台上,而不会显示到终端上。也就是说,控制台是计算机的基本设备,而终端是附加设备。 当然,由于控制台也有终端一样的功能,控制台有时候也被模糊的统称为终端。 计算机操作系统中,与终端不相关的信息,比如内核消息,后台服务消息,都可以显示到控制台上,但不会显示到终端上。

    简单的说,能直接显示系统消息的那个终端称为控制台,其他的则称为终端。但是在linux系统中,这个概念也已经模糊化了

    比如下面这条命令:

    echo "hello,world" > /dev/console 
    

    这条命令的目的是将"hello,world"显示到控制台上。/dev/console是控制台设备的设备名。在linux中,在字符模式下,你无论在哪个虚拟终端下执行这条命令,字符hello,world都会显示在当前的虚拟终端下。也就是说,linux把当前的虚拟终端当作控制台来看待。可见,linux中已经完全淡化了控制台和终端的区别。但是在其他的UNIX类系统中,却很明显的有虚拟终端和控制台的区别。比如freeBSD系统。

    在freebsd中,只有第一个“终端”才是真正的控制台。(就是说按alt+f1得到的那个虚拟终端) ,你无论在哪个虚拟终端上执行上面的那条命令(哪怕是通过网络连接的伪终端上执行这条命令)。hello,world字符总会显示到第一个“终端”也就是真正的控制台上。另外,其他的一些系统内部信息,比如哪个用户在哪个终端登陆,系统有何严重错误警告等信息,全都显示在这个真正的控制台上。在这里,就明显的区分了终端和控制台的概念。

    再简单的说,控制台是直接和计算机相连接的原生设备,终端是通过电缆、网络等等和主机连接的设备

  • 控制终端:

    对应的文件是/dev/tty

    这是一个逻辑概念,即用户正在控制的终端,可以为串行终端,虚拟终端和伪终端。

  • 其它类型

    Linux系统中还针对很多不同的字符设备存在有很多其它种类的终端设备特殊文件。例如针对ISDN设备的/dev/ttyIn终端设备等

1.3 通过终端登录Unix系统的过程

在这里插入图片描述

  1. 当系统启动时,内核创建进程ID为1的进程也就是init进程,init进程使系统进入多用户状态。init进程根据配置文件/etc/inittab确定需要打开哪些终端(这个配置文件中的每一项记录了终端设备名和要传到getty程序的参数等,如该终端设备的波特率),对每一个允许登录的终端设备,init调用一次fork,它所生成的子进程则执行getty(exec)程序。(不同操作系统配置文件可能不同)

  2. getty通过open函数以读写方式打开该终端设备(把文件描述符0、1、2都指向该控制终端)。然后getty输出longin:之类的信息,并等待用户键入用户名。

  3. 当用户键入用户名后,getty工作完成。然后以类似以下形式调用login程序

    execle(/bin/login”,”login”,-p”,username,(char *)0,envp)
    

    init以一个空环境调用getty,getty则为login创建一个环境(envp参数,意为环境表)。-p参数意为通知login程序保留传递给它的环境(可以添加该环境表中的环境变量,但是不能替换它)。

  4. login处理多项工作,由于它的命令行参数有用户名,因此它能调用getpwnam取得相应用户的口令文件登录项,然后显式提示Password:,且在输入密码期间关闭终端的回显,因此我们在linux下输入密码时是看不到的,然后验证帐号密码的正确性。

    login程序读取用户键入的口令,将该口令加密并与阴影文件中对应项相比较。密码验证无误后,login程序做如下工作(但是如果用户几次键入口令无效,则login调用exit(1)。父进程了解到子进程的终止情况后,将再次调用fork,然后执行getty,然后重复此功能。):

    • login将切换目录到用户的home目录

    • 调用chown更改该终端的所有权,使登录用户成为它的所有者

    • 对该终端设备的访问权限改为“用户读和写”

    • 调用setgid和initgroups设置进程的组ID

    • 用login得到的所有信息初始化环境:起始目录HOME、SHELL、用户名USER和LOGNAME以及系统默认路径PATH

    • login更改进程权限(由于是init进程fork的子进程,因此之前一直是超级用户权限),通过setuid将进程的用户ID更改为登录用户的用户ID(由于setuid是由超级用户调用的,因此它更改所有3个用户ID&

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值