分类:
2008-11-28 13:54:08
9 process relationships
9.2 terminal logins
这个terminal logins其实就是本地登陆,即使用与host相连的硬件terminal登录。流程如下:
我们只管linux:
1.Init进程启动后,读取/etc/inittab文件,获知要启动哪些terminal,针对每一个要启动的terminal都fork出一个子进程,然后exec gettty,来处理各个terminal. 即一个进程负责一个terminal的login管理。
2. gettty的descriptor 0,1,2都对应了他打开的terminal。getty等待用户输入username。
3.用户输入了username后,getty工作完了,他exec login。
4.Login负责要求用户输入密码,根据用户输入的密码,然后加密再与系统保存的密码比较,来看是否成功匹配。如果没有,就从新要求输入密码。重复若干次后,若果都失败了,login就退出了。此时,由于login是由子init, getty一路exec出来的,所以login的父亲就是最开始的init, 那么init收到了login结束时发出的SIGCHLD信号,就在此spawn出一个子进程然后exec getty,其流程同上。
5.如果密码匹配了,就登录成功了,此时login会设置一些环境变量,PATH, HOME,LOGNAME, USER等, 还会执行一个login shell具体工作如下:
If we log in correctly, login will
·
execl("/bin/sh",
"-sh", (char *)0);
The minus sign as the first character of argv[0] is a
flag to all the shells that they are being invoked as a login shell. The shells
can look at this character and modify their start-up accordingly.
由于此时login是superuser,调用setuid和setgid会设置本进程的real usrer id, effective user id , saved set-user-id都为被设置的id.
Login shell被启动了,它是根据其第一个参数中包含的‘-’字符来知道自己是要以login shell的形式启动的,他会读取/etc/.profile等文件。这就是login shell的startup file。
在login shell里,descriptor 0,1,2就依然对应了开始的terminal。对这些descriptor 的读写会转化为系统调用,最中会调用到该terminal的driver,从而控制通过hardware line连接的终端设备。
9.3 network logins
在直接用terminal登录的时候,由于在/etc/inittab中记录了有多少个可用于login的teminnal,所以可以fork出若干个getty进程去分别管理这几个terminal。但是在网络环境下,你不知道要有多少人来通过网络登陆,所以不能采取提前fork进程的方法。
还要注意的是,应该尽两使用与terminal相似的机制,尽量不做新的功能,而terminal登录需要terminal,所以需要一种假的terminal,它模拟出一个serial terminal,那么以前那些使用terminal的login程序就依然可以工作了(login 将自己的descriptor 0,1,2都影射到该pseudo terminal就可以了)。
工作流程:
1.Init在初始化的时候,曾见fork出一个进程来执行/etc/rc脚本文件作初始化,这个脚本曾启动了一个名为inetd,或者xinetd的dameon进程
2. xinetd负责检查网络,一旦收到了某client发来的对telnet服务的request,就打开一个fork出一个子进程然后exec telnetd.
3. telnetd负责管理telnet连接,也负责TELNET协议的使用,他打开一个pseudo terminal,自己管理master端,然后fork出一个子进程,将已经打开的pseudo terminal影射为自己的descriptor 0,1,2然后exec login进程。
4.Login进程此时有了1,2,3,descriptor,他就认为自己连接上了terminal,于是就执行与9.2种相同的流程了。那么毕竟这是通过网络,需要将一切转换为网络数据发送。这个工作就成了telnetd的了。
5.Telnetd负责在pseudo terminal的master端接收login管理的slave端发来的数据,然后使用TELNET协议发送出去。以及将从client发来的数据经过TELNET协议处理,通过pseudo terminal传给login。
不管是使用普通terminal还是使用pseudo terminal,login都将自己的descriptor 0,1,2连接到terminal上,这个terminal也就是后来我们提到的这个session的control terminal。