菜鸟学习,欢迎指正。
控制终端是用户登入时的终端设备(ttyn)或伪终端设备(ttysn、pts/n)。
每次登入就是一个会话,当然也可以setsid()重新生成一个会话;每个会话只有一个前台进程组和若干后台进程组,只有前台进程组拥有控制终端,也就是前台进程组可以利用控制终端进行输入输出,从控制终端发送的SIGINT(ctrl+c)和SIGQUIT(ctrl+\)只发送给前台进程组的所有进程。
从守护进程看进程组的关系:
守护进程的目的是利用一个父进程看守子进程的状态,即在子进程退出时避免僵尸进程的产生(一般子进程退出时向父进程发送SIGCHLD信号,父进程IGN忽略这种信号OK了)。守护进程本身是一个后台进程,并且从属于一个独立的会话(不同于用户登入时生成的会话),并且该进程禁止打开控制终端。
1,实现新的会话:因为进程组的组长进程不能setsid(),所以fork()生成子进程,父进程退出,子进程变为孤儿进程。子进程调用setsid(),变为一个新的会话的进程组的组长。
2,禁止会话重新打开控制终端: 新的会话是不给分配控制终端的,但是组长进程是可以重新打开控制终端的(open(filename,...),filename为/dev/ttyn),因此再一次fork(),父进程退出。
3,清理工作:关闭从父进程继承的打开的文件描述符fd,清除父进程继承的文件访问掩模umask(),重置当前工作目录,设置对子进程信号的处理方式。