(1) 调用umask将文件模式创建屏蔽字设置为0
(2)调用fork,然后使父进程退出(exit)。这样做实现以下几点:第一,如果该守护进程是作为一条简单的shell命令启动的,那么父进程终止使得shell认为这条命令已经执行完毕;第二,子进程继承了父进程的进程组ID,但具有一个新的进程ID,这就保证了子进程不是一个进程组的组长进程
(3)调用setsid以创建一个新会话,使调用进程:成为会话首进程、成为一个新进程组的组长进程、没有控制终端
(4)将当前工作目录改为根目录
(5)关闭不在需要的文件描述符
(6)某些守护进程打开/dev/null使其具有文件描述符0、 1和2,这样任何一个试图读标准输入、写标准输出、或标准出错的库例程不会产生任何效果
下面是具体的程序
void init_daemon(void) { int pid; int i; umask(0); //重设文件创建掩模 if(pid=fork()) exit(0); //是父进程,结束父进程 else if(pid< 0) exit(1); //fork失败,退出 //是第一子进程,后台继续执行 setsid(); //第一子进程成为新的会话组长和进程组长 //并与控制终端分离 if(pid=fork()) exit(0); //是第一子进程,结束第一子进程 else if(pid< 0) exit(1); //fork失败,退出 //是第二子进程,继续 //第二子进程不再是会话组长 for(i=0;i< NOFILE;++i) //关闭打开的文件描述符 close(i); //dup standard i/o int fd; fd=open("/dev/null",O_RDWR,0); f(fd!=-1) { dup2(fd,STDIN_FILENO); dup2(fd,STDOUT_FILENO); dup2(fd,STDERR_FILENO); close(fd); } chdir("/tmp"); //改变工作目录到/tmp return; }