通过串行终端登录至系统和经由网络登录至系统两者之间的主要(物理上的)区别是:通过网络登录时,终端和计算机之间的连接不是点对点连接。在这种情况下,login只是一种可用的服务,这与其他网络服务(例如FTP或SMTP)的性质相同。
在终端登录中,init知道哪些终端设备可用来进行登录,并为每个设备生成一个getty进程。但是在网络登录情况下,所有登录都经由内核的网络接口驱动程序(如以太网驱动程序),事先并不知道将会有多少这样的登录。我们不是使一个进程等待每个可能的登录,而是必须等待一个网络连接请求的到达。
为使同一软件即能处理终端login,又能处理网络login,系统使用了一种称为伪终端(pseudo terminal)的软件驱动程序,它仿真串行终端的运行行为,并将终端操作映射为网络操作,反之亦然。
1、BSD网络登录在BSD中,有一个称为inetd的进程(有时称之为因特网超级服务器),它等待大多数网络连接。
作为系统启动的一部分,init调用一个shell,使其执行shell脚本/etc/rc。由此shell脚本启动一个守护进程inetd。一旦此shell脚本终止,inetd的父进程就变成init。inetd等待TCP/ip连接请求到达主机,而当一个连接请求到达时,它执行一次fork,然后生成的子进程执行适当的程序。
我们假定到达了一个针对TELNET服务进程的TCP连接请求。TLENET是使用TCP协议的远程登录应用程序。在另一台主机(它通过某种形式的网络与服务进程的主机相连接)上的用户,或在同一台主机上的用户启动TELNET客户端进程,由此启动登录过程:
telnet hostname
该客户进程打开一个到hostname主机的TCP连接,在hostname主机上启动的程序被称为TELNET服务进程。然后,客户进程和服务进程之间使用TELNET应用协议通过TCP连接交换数据。所发生的是启动客户进程的用户现在登录到了服务进程所在的主机。(自然,用户需要在服务进程主机上有一个有效的账号)。
然后,telnetd进程(TELNET服务进程)打开一个伪终端设备,并用fork分成两个进程。父进程处理通信网络连接的通信,子进程则执行login程序。父、子进程通过伪终端相连接。在调用exec之前,子进程使其文件描述符0、1、2与伪终端相连。如果登录正确,login就执行与终端登录中同样的步骤:更改当前工作目录为起始目录,设置登录用户的组ID和用户ID,以及登录用户的初始环境。然后login调用exec将其自身替换为登录用户的登录shell。
需要理解的重点是:当通过终端或网络登录时,我们得到一个登录shell,其标准输入、输出和标准出错连接到一个终端设备或者伪终端设备上。这一登录shell是POSIX.1会话的开始,而此终端或伪终端则是会话的控制终端。
2、linux网络登录除了使用扩展的因特网服务守护进程xinetd替代inetd进程外,Linux网络登录的其他方面与BSD相同。xinetd进程对它所启动的各种服务的控制比inetd提供的更加精细。
本篇博文内容摘自《UNIX环境高级编程》(第二版),仅作个人学习记录所用。关于本书可参考:http://www.apuebook.com/。
新闻热点
疑难解答