从http://www.steve.org.uk/Reference/Unix/faq_2.html#SEC16
以下是成为守护进程的步骤:
- fork()以便父级可以退出,这会将控制权返回到调用程序的命令行或shell.此步骤是必需的,以确保新流程不会成为流程组长.如果您是流程组长,下一步setsid()将失败.
- setsid()成为流程组和会话组组长.由于一个控制终端与一个会话相关联,而这个新会话还没有获得一个控制终端,所以我们的进程现在没有控制终端,这对守护进程来说是件好事.
- 再次使用fork(),以便家长(会话组组长)可以退出.这意味着,作为非会话组组长,我们永远无法重新获得控制终端.
- chdir("/"),以确保我们的进程不会使用任何目录.如果不这样做,管理员可能无法卸载文件系统,因为它是我们当前的目录.[等效地,我们可以更改到包含对守护程序操作重要的文件的任何目录.]
- umask(0),这样我们就可以完全控制我们所写的任何东西的权限.我们不知道我们可能继承了什么.[此步骤是可选的]
- 关闭()fds 0、1和2.这将释放我们从父进程继承的标准输入、输出和错误.我们无法知道这些FD可能被重定向到了哪里.请注意,许多守护进程都使用sysconf()来确定限制_SC_OPEN_MAX._SC_OPEN_MAX告诉您最大打开文件/进程数.然后在循环中,守护进程可以关闭所有可能的文件描述符.你必须决定是否需要这样做.如果您认为可能有打开的文件描述符,您应该关闭它们,因为并发文件描述符的数量是有限的.
- 为stdin、stdout和stderr建立新的开放描述符.即使你不打算使用它们,打开它们仍然是一个好主意.对这些问题的精确处理取决于品味;例如,如果您有一个日志(log)文件,您可能希望将其作为stdout或stderr打开,并将"/dev/null"作为stdin打开;或者,您可以将"/dev/console"作为stderr和/或stdout打开,将"/dev/null"作为stdin打开,或者对特定守护进程有意义的任何其他组合.
更好的是,只要调用daemon()函数就可以了.