13-01-24-->9

来源:互联网 发布:oracle数据同步工具 编辑:程序博客网 时间:2024/06/03 20:19

终端登录

登录都经由内核中的终端设备驱动程序。

/etc/ttys(Linux 为/etc/inittab)文件,其中,每个终端设备都有一行(每行包括设备名和传递给getty程序的参数)。

UNIX系统传统的用户身份验证过程:当系统自举时,内核创建init(ID为1)进程。init使系统进入多用户状态。init进程读/etc/ttys,对每一个允许登录的终端设备,init调用一次fork,它所生成的子程序则执行(exec) getty程序。getty为终端设备调用open函数,以读、写方式将终端打开。getty输出“login:”,用户输入用户名后,getty工作就完成了。之后调用login。login可以执行多项工作。因为它得到了用户名,能调用gepwnam取得相应用户的口令文件登录项。之后调用getpass以显示提示“Passwd”,接着读用户键入的口令。它调用crypt将用户键入的口令加密,并与该用户在shadow口令文件中登录项的pw_passwd字段相比较。



login进程改变为登录用户的用户ID(setuid)并调用该用户的登录shell : execl("/bin/sh","-sh",(char *)0);

登录用户的登录shell开始运行。其父进程ID是init进程ID。


网络登录

init调用一个shell,使其执行shell脚本/etc/rc,由此shell脚本启动守护进程inetd(Linux下启动xinetd守护进程)。一旦此shell脚本终止,inetd的父进程就变成init。inted等待TCP/IP连接请求到达主机,而当一个连接请求到达时,它执行一次fork,然后生成的子进程执行适当的程序。e.g.telnetd进程。此进程打开一个伪终端设备,并用fork分成两个进程。父进程处理通过网络连接的通信,子进程则执行login程序。后续同上。。。



当通过终端或网络登录时,我们得到一个登录shell,其标准输入、输出和标准出差连接到一个终端设备或者伪终端设备。

这一登录shell是一个会话的开始,而此终端或伪终端则是会话的控制终端。


进程组

pid_t getpgrp(void); 返回调用进程的进程组ID.

每个进程组都可以有一个组长进程。组长进程的标识是,其进程组ID等于其进程ID。

int setpgid(pid_t pid, pid_t pgid);加入一个现有的组或者创建一个新进程组。


会话

会话(session)是一个或多个进程组的集合。

pid_t setsid(void);建立一个新会话。调用进程不能是一个进程组的组长,不然函数返回出错。为了保证不会发生此种情况,通常先调用fork,然后使其父进程终止,而子进程继续。因为子进程继承了父进程的进程组ID,而其进程ID是新分配的,两者不可能相等。所以子进程不会是一个进程组长。

pid_t getsid(pid_t pid);返回会话首进程的进程组ID。


控制终端



用来通知内核哪一个进程组是前台进程组,这样,终端设备驱动程序就能了解将终端输入和终端产生的信号送到何处。

tcgetpgrp(int); tcsetgpgrp(int,pid_t);


作业控制

允许在一个终端上启动多个作业(进程组),它控制哪一个作业可以访问终端,以及哪些作业在后台运行。一个作业只是几个进程的集合,通常是一个进程的管道线

当作业已完成而且我们键入回车时,shell通知我们作业已完成。键入回车是为了让shell打印其提示符。shell并不在任何随意时刻打印后台作业的状态改变,它只在打印其提示符让用户输入新的命令之前才这样做。如果不这样处理,则当我们正输入一行时,它也可能输出。

能使终端驱动程序产生信号,并将他们送至前台进程组:1.中断Ctrl^c,产生SIGINT  2.退出字符 Ctrl^\,产生SIGQUIT 3.挂起字符 Ctrl^z 产生SIGTSTP

只有前台作业接受终端输入。后台要试图读终端,并不是一个错误,此时终端驱动程序检测到这种情况,并且向后台程序发送一个SIGTTIN信号,该信号会暂时停止后台作业,而shell则向用户发出这种情况通知。用户可用shell命令将此作业转为前台作业。这样作业置入前台进程组(tcsetpgrp),并将SIGCONT送给进程组,于是它就可以读终端。

如果后台试图输出到控制终端,通过允许or禁止选项来改变。e.g.stty命令。



孤儿进程组

即 该组中的每个成员的父进程要么是该组的一个成员,要么不是该组所属会话的成员。

程序清单9-1:因为在父进程终止后,进程组称为孤儿进程组。向新的孤儿进程组中处于停止状态的每一个进程发送挂断信号(SIGHUP),接着又向其发送继续信号(SIGCONT)


会话和进程组的实现:




原创粉丝点击