Chinaunix首页 | 论坛 | 博客
  • 博客访问: 968683
  • 博文数量: 200
  • 博客积分: 5011
  • 博客等级: 大校
  • 技术积分: 2479
  • 用 户 组: 普通用户
  • 注册时间: 2008-06-27 15:07
文章分类

全部博文(200)

文章存档

2009年(12)

2008年(190)

我的朋友

分类:

2008-11-28 13:54:08

9 process relationships

9.2 terminal logins

这个terminal logins其实就是本地登陆,即使用与host相连的硬件terminal登录。流程如下:

我们只管linux:

1Init进程启动后,读取/etc/inittab文件,获知要启动哪些terminal,针对每一个要启动的terminalfork出一个子进程,然后exec gettty,来处理各个terminal. 即一个进程负责一个terminallogin管理。

2. getttydescriptor 012都对应了他打开的terminalgetty等待用户输入username

3.用户输入了username后,getty工作完了,他exec login

4Login负责要求用户输入密码,根据用户输入的密码,然后加密再与系统保存的密码比较,来看是否成功匹配。如果没有,就从新要求输入密码。重复若干次后,若果都失败了,login就退出了。此时,由于login是由子init, getty一路exec出来的,所以login的父亲就是最开始的init, 那么init收到了login结束时发出的SIGCHLD信号,就在此spawn出一个子进程然后exec getty,其流程同上。

5.如果密码匹配了,就登录成功了,此时login会设置一些环境变量,PATH, HOMELOGNAME, USER, 还会执行一个login shell具体工作如下:

If we log in correctly, login will

  • Change to our home directory (chdir)
  • Change the ownership of our terminal device (chown) so we own it
  • Change the access permissions for our terminal device so we have permission to read from and write to it
  • Set our group IDs by calling setgid and initgroups
  • Initialize the environment with all the information that login has: our home directory (HOME), shell (SHELL), user name (USER and LOGNAME), and a default path (PATH)
  • Change to our user ID (setuid) and invoke our login shell, as in

·                        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.

由于此时loginsuperuser,调用setuidsetgid会设置本进程的real usrer id, effective user id , saved set-user-id都为被设置的id.

Login shell被启动了,它是根据其第一个参数中包含的‘-’字符来知道自己是要以login shell的形式启动的,他会读取/etc/.profile等文件。这就是login shellstartup file

login shell里,descriptor 0,1,2就依然对应了开始的terminal。对这些descriptor 的读写会转化为系统调用,最中会调用到该terminaldriver,从而控制通过hardware line连接的终端设备。

9.3 network logins

在直接用terminal登录的时候,由于在/etc/inittab中记录了有多少个可用于loginteminnal,所以可以fork出若干个getty进程去分别管理这几个terminal。但是在网络环境下,你不知道要有多少人来通过网络登陆,所以不能采取提前fork进程的方法。

还要注意的是,应该尽两使用与terminal相似的机制,尽量不做新的功能,而terminal登录需要terminal,所以需要一种假的terminal,它模拟出一个serial terminal,那么以前那些使用terminallogin程序就依然可以工作了(login 将自己的descriptor 0,1,2都影射到该pseudo terminal就可以了)。

工作流程:

1Init在初始化的时候,曾见fork出一个进程来执行/etc/rc脚本文件作初始化,这个脚本曾启动了一个名为inetd,或者xinetddameon进程

2. xinetd负责检查网络,一旦收到了某client发来的对telnet服务的request,就打开一个fork出一个子进程然后exec telnetd.

3. telnetd负责管理telnet连接,也负责TELNET协议的使用,他打开一个pseudo terminal,自己管理master端,然后fork出一个子进程,将已经打开的pseudo terminal影射为自己的descriptor 0,1,2然后exec login进程。

4Login进程此时有了123descriptor,他就认为自己连接上了terminal,于是就执行与9.2种相同的流程了。那么毕竟这是通过网络,需要将一切转换为网络数据发送。这个工作就成了telnetd的了。

5Telnetd负责在pseudo terminalmaster端接收login管理的slave端发来的数据,然后使用TELNET协议发送出去。以及将从client发来的数据经过TELNET协议处理,通过pseudo terminal传给login

不管是使用普通terminal还是使用pseudo terminallogin都将自己的descriptor 0,1,2连接到terminal上,这个terminal也就是后来我们提到的这个sessioncontrol terminal
阅读(806) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~