int daemon(int nochdir, int noclose);
参数:
nochdir:当此参数为0时,会更改创建出的danmon的执行目录为根目录,否则(非0)时保持当前执行目录不变。
noclose:当次函数为0时,会将标准输入(0),标准输出(1),标准错误(2)重定向到/dev/null,否则保持原有标准输入(0),标准输出(1),标准错误(2)不变。
无论noclose 是否为0,daemon函数都不会关闭之前打开的大于等于3的fd。但是如果noclose值为0,需要确保0,1,2三个fd没有用于打开其他文件。下面一段程序就有问题,
int main(void)
{
int fd1, fd2, fd3;
close(0);
close(1);
close(2);
fd1 = open("/tmp/tmp", O_RDWR, 0);
fd2 = open("/tmp/tmp", O_RDWR, 0);
fd3 = open("/tmp/tmp", O_RDWR, 0);
daemon(0, 1);
sleep(100);
}
用户将0,1,2三个fd用于打开文件而不是标准输入(0),标准输出(1),标准错误(2),但是daemon函数依旧会将0,1,2三个fd重定向到/dev/null(可通过lsof命令查看打开文件情况),所有后面的daemon进程并不能通过0,1,2三个fd访问到文件。
在使用daemon函数的程序中,可在最初调用打开文件函数或创建socket函数前,使用如下函数,确保0,1,2三个fd不会被用于标准输出、输入、错误外的其他用途。
static inline void sanitize_fds(void)
{
int zero;
if ((zero = open("/dev/null", O_RDWR, 0)) < 0) return;
while (zero < 3) zero = dup(zero);
close(zero);
}