根据 UNIX环境 第13章的Stevens 高级编程 ,这是制作行为良好的Unix守护程序的过程:
- 分叉并有父出口。这使Shell或引导脚本认为命令已完成。此外,保证子进程不会成为进程组负责人(下一个setsid的先决条件)
- 呼叫
setsid
以创建一个新的会话。这做三件事:- 该过程成为新会话的会话负责人
- 该流程成为新流程组的流程组负责人
- 该过程没有控制终端
- (可选)再次分叉并具有父出口。这确保守护程序不是会话领导者,也不能获取控制终端(在SVR4下)
- 更改当前工作目录,
/
以避免干扰安装和卸载 - 将文件模式创建掩码设置为000,以允许以后创建具有任何必需权限的文件。
- 继承自父关闭不需要的文件描述符(没有控制终端反正): ,
stdout
,stderr
和stdin
。
如今,有一个文件可以跟踪PID,Linux发行引导脚本经常使用该文件。确保写出孙子的PID,第二个fork的返回值(步骤3)或
getpid()步骤3之后的值。
这是一个Ruby实现,大部分是从书中翻译过来的,但是带有双叉并写出了守护进程PID。
# Example double-forking Unix daemon initializer.raise 'Must run as root' if Process.euid != 0raise 'First fork failed' if (pid = fork) == -1exit unless pid.nil?Process.setsidraise 'Second fork failed' if (pid = fork) == -1exit unless pid.nil?puts "Daemon pid: #{Process.pid}" # Or save it somewhere, etc.Dir.chdir '/'File.umask 0000STDIN.reopen '/dev/null'STDOUT.reopen '/dev/null', 'a'STDERR.reopen STDOUT


