精灵进程

13.3 编程规则
在编写精灵进程程序时需遵循一些基本规则,以便防止产生并不希望的交互作用。
下面先说明这些规则,然后是一个按照规则编写的函数daemon-init。
1. 首先做的是调用fork,然后使父进程终止。这样做实现了下面几点。第一,如
果该精灵进程是由一条简单shell命令启动的,那么使父进程终止使得shell认为这
条命令已经执行完成。第二,子进程继承了父进程的进程组ID,但具有一个新的进
程ID,这就保证了子进程不是一个进程组的首进程。这对于下面就要做的setsid调
用是必要的前提条件。
2. 调用setsid以创建一个新对话期。于是执行9.5节中列举的三个操作。使调用进
程:(1)成为新对话期的首进程,(2)成为一个新进程组的首进程,(3)没有
控制终端。
在SVR之下,有些人建议在此时再调用fork,并使父进程终止。第二个子进程作为
精灵进程继续运行。这样就保证了该精灵进程不是对话期首进程,于是按照SVR4规
则(见9.6节)可以防止它取得控制终端。另一方面,为了避免取得控制终端,无
论何时打开一个中断设备都要指定O-NOCTTY。
3. 将当前工作目录更改为根目录。从父进程继承过来的当前工作目录可能在一个
装配的文件系统中。因为精灵进程通常在系统再引导之前是一直存在的,所以如果
精灵进程的当前工作目录在一个装配文件系统中,那么该文件系统就不能被拆卸。

另外,某些精灵进程可能会把当前工作目录更改到某个指定位置,在此位置做它们
的工作。例如,行式打印机假脱机精灵进程常常将其工作目录更改到它们的spool
目录上。
4. 将文件方式创建屏蔽字设置为0。由继承得来的文件方式创建屏蔽字可能会拒绝
设置某些许可权。例如,若精灵进程要创建一个组可读、写的文件,而继承的文件
方式创建屏蔽字,屏蔽了这两种许可权,则所要求的组可读、写就不能起作用。
5. 关闭不再需要的文件描述符。这样使精灵进程就不再持有从其父进程继承来的
某些文件描述符(父进程可能是shell进程,或某个其它进程)。但是,究竟关闭
那些描述符则与具体的精灵进程有关,所以在下面的例子中不包含此步骤。可以使
用程序2.3中的open_max函数来决定最高文件描述符值,并关闭直到该值的所有描
述符。

这是APUE关于精灵进程的创建对则:

对我们下面的程序有指导,关于上面对话其,进程组以及setsid函数参看上一篇博文:

下面是一个精灵进程初始化的程序:

 #include <sys/types.h>
  2 #include <sys/stat.h>
  3 #include <fcntl.h>
  4 #include "../../ourhdr.h"
  5
  6 int daemon_init (void)
  7 {
  8         pid_t pid;
  9
 10         if ( (pid = fork()) < 0)
 11                 return (-1);
 12         else if (pid != 0)
 13                 exit(0);
 14         /*parent goes bye-bye*/
 15
 16         /*child continues*/
 17         setsid();
 18         /*become session leader*/
 19
 20         chdir("/");
 21         /*change working directory*/
 22
 23         umask(0);
 24         /*clear our file mode creation mask*/
 25         return(0);
 26
 27 }
 28
由于这个程序是完全按照上面的规则写的。所以不多解释:

然后在一个程序中调用该函数:调用程序为:

 #include <stdio.h>
  2
  3 int main()
  4 {
  5         daemon_init();
  6         pause();
  7 }
~      

这样竟能生成一个精灵进程:

/****************************************************************************************************************************************************/

精灵进程的观察:

先看看精灵进程的性质:

所有精灵进程都以超级用户(用户ID为0)的优先权运行。没有一个精灵进
程具有控制终端-终端名称设置为问号(?)、终端前台进程组ID设置为-1。缺少
控制终端可能是精灵进程调用了setsid的结果。除update以外的所有精灵进程都是
进程组的首进程,对话期的首进程,而且是这些进程组和对话期中的唯一进程。u
pdate是它所在进程组(37)和对话期(37)中的唯一进程,但是该进程组的首进
程(可能也是该对话期的首进程)已经终止。最后,应当引起注意的是所有这些精
灵进程的父进程都是init进程。

根据这些性质可以让我们在启动的那么多进程中比较容易找到精灵进程:

ps -axj | grep "/-1"

这样可以看到精灵进程:

你可能感兴趣的:(编程,工作,shell,session,File,终端)