第9章

作者: cde99bf0b5b1 | 来源:发表于2017-08-31 12:57 被阅读0次

    第九章 进程关系


    9.2 终端登录

    终端类型:基于字符的终端、仿真基于字符终端的图形终端、运行窗口系统的图形终端
    BSD终端登录如下:

    1. 系统启动时,内核创建init进程(进程号为1),init进程使系统进入多用户模式。init读取文件/etc/ttys(每个终端设备都占有一行,每一行说明设备名和传到getty程序的参数),对每一个允许登录的终端设备,init调用一次fork,它所生成的子进程以空环境exec getty程序。

    2. getty对终端设备调用open函数,以读写方式将终端打开(文件描述符0,1,2关联到终端设备),然后getty输出“login:"之类的信息,并等待用户输入用户名。当用户输入用户名之后,getty程序的工作就做完了。

    3. getty程序完成之后,调用login程序:
      execle("/bin/login", "login", "-p", username, (char*)0, envp);

    4. login可以用于验证密码,并且完成以下工作:

    • 将当前工作目录更改为该用户的起始目录
    • 调用chown更改该终端的所有权,使登录用户成为它的所有者
    • 将对终端设备的访问权限改变为”用户读和写“
    • 调用 setgid 以及 initgroups 设置进程的组ID
    • 用login得到的所有信息初始化环境
    • login进程更改为登录用户的用户ID(setuid)并且调用该用户的登录shell:
      execl("/bin/sh", "-sh", (char*)0);

    总流程:
    init(进程ID为1)--fork-->init(进程ID不为1)--exec-->getty(打开终端设备,读用户名,初始环境集)--exec-->login(...)--exec-->登录shell<--fd 0,1,2-->终端设备驱动<--硬连接-->终端用户

    9.3 网络登录

    BSD网络登录如下:

    1. init进程调用shell,使其执行shell脚本/etc/rc。此脚本启动守护进程inetd。一旦此shell脚本终止,inetd的父进程就变成init。inetd等待网络连接到达主机。

    2. 当网络请求到来时,inetd执行fork,然后子进程exec。

    例:在TELNET服务进程的TCP连接请求到达时:即telnet hostname

    1. telnetd进程打开一个伪终端设备,并用fork分成两个进程。父进程处理网路连接的通信,子进程执行login程序。父进程和子进程通过伪终端相连接。子进程在调用exec login之前,子进程使其文件描述符0,1,2与伪终端相连。登录正确的话,login执行和终端登录中login相同的步骤。然后login调用exec将其自身替换为登录shell。

    init-->inetd-->inetd-->telnetd-->login-->登录shell<--->伪终端设备驱动<-->终端用户

    9.4 进程组

    #include <unistd.h>
    pid_t getpgrp(void);//返回调用进程的进程组ID
    
    #include <unistd.h>
    pid_t getpid(pid_t pid);
    成功返回进程组ID,失败返回-1
    

    getpgid(0) == getpgrp()
    调用setpgid可以将进程加入到一个现有的进程组或者创建一个新进程组。

    #include <unistd.h>
    int setpgid(pid_t pid, pid_t pgid);
    成功返回0,出错返回-1
    

    如果pid == pgid,则由pid指定的进程就变成进程组组长。
    如果pid是0,则使用调用者的进程ID。
    如果pgid是0,则pid指定的进程ID用作进程组ID。

    进程只能为它自己或者它的子进程设置进程组ID。但是它的子进程调用了exec后,它就不再更改子进程的进程组ID。

    相关文章

      网友评论

          本文标题:第9章

          本文链接:https://www.haomeiwen.com/subject/umlqjxtx.html